poj2594-Treasure Exploration(最小路径覆盖,最大匹配,floyed(优化))

来源:互联网 发布:巡店软件 编辑:程序博客网 时间:2024/05/17 03:47

题目来源:http://poj.org/problem?id=2594

题意

有好多机器人去一个DAG(有向无环图)寻宝藏,问,最少放置几个才可以遍历所有点。

思路

这道题挑明了就是类似hdu1051的题目,求得是最小路径覆盖问题,只不过那道题的伞兵不可移动,而这里的机器人可移动,所以能够移动的话,就代表:mp[1][2]=1,mp[2][3]=1,那么mp[1][3]=1。
所以事先会利用floyed的思想去预处理一下。。。交的时候瞅了一眼时间限制,。。哇,,6000ms,那我就放心了。。。嘿嘿

代码

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=500+10;int mp[maxn][maxn],pre[maxn],vis[maxn];int n,m;void init(){    memset(mp,0,sizeof(mp));    while(m--)    {        int l,r;        scanf("%d%d",&l,&r);        mp[l][r]=1;    }    for(int i=1;i<=n;i++)    {        for(int j=1;j<=n;j++)        {            if(mp[i][j])  continue;            for(int k=1;k<=n;k++)            {                if(mp[i][k]&&mp[k][j])                {                    mp[i][j]=1;                }            }        }    }}int dfs(int i){    for(int j=1; j<=n; j++)    {        if(mp[i][j]&&!vis[j])        {            vis[j]=1;            if(pre[j]==-1||dfs(pre[j]))            {                pre[j]=i;                return 1;            }        }    }    return 0;}void solve(){    int ret=0;    memset(pre,-1,sizeof(pre));    for(int i=1; i<=n; i++)    {        memset(vis,0,sizeof(vis));        ret+=dfs(i);    }    printf("%d\n",n-ret);}int main(){    while(~scanf("%d%d",&n,&m)&&(n||m))    {        init();        solve();    }}
阅读全文
0 0