POJ2594 Treasure Exploration(最小路径覆盖+传递闭包)

题意:

派机器人去火星寻宝,给出一个无环的有向图,机器人可以降落在任何一个点上,

再沿着路去其他点探索,我们的任务是计算至少派多少机器人就可以访问到所有的点。点可以重复去

思路:

最小路径覆盖,只是点可以重复去,就需要求传递闭包,用floyd

 

/* ***********************************************
Author        :devil
Created Time  :2016/5/17 16:45:13
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
const int N=510;
int link[N],n;
bool mp[N][N],vis[N];
bool dfs(int u)
{
    for(int i=1; i<=n; i++)
    {
        if(mp[u][i]&&!vis[i])
        {
            vis[i]=1;
            if(link[i]==-1||dfs(link[i]))
            {
                link[i]=u;
                return 1;
            }
        }
    }
    return 0;
}
void floyd()
{
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            if(mp[i][j]==0)
                for(int k=1; k<=n; k++)
                    if(mp[i][k]&&mp[k][j])
                    {
                        mp[i][j]=1;
                        break;
                    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int m,x,y;
    while(~scanf("%d%d",&n,&m)&&(n+m))
    {
        memset(link,-1,sizeof(link));
        memset(mp,0,sizeof(mp));
        while(m--)
        {
            scanf("%d%d",&x,&y);
            mp[x][y]=1;
        }
        floyd();
        int ans=0;
        for(int i=1; i<=n; i++)
        {
            memset(vis,0,sizeof(vis));
            ans+=dfs(i);
        }
        printf("%d\n",n-ans);
    }
    return 0;
}

 

posted on 2016-05-17 16:46  恶devil魔  阅读(216)  评论(0编辑  收藏  举报

导航