POJ 2594 Treasure Exploration (floyd判断联通+最小路径覆盖)

来源:互联网 发布:淘宝怎么申请二次售后 编辑:程序博客网 时间:2024/05/17 07:58

题目链接:http://poj.org/problem?id=2594


题意:有n个点,m条单向路径,问需要最小几个机器人可以遍历所有的点,已经走过的点可以再走


思路:一开始还以为和上一题一样然后就gg了……,关键点在于走过的点可以重复走,也就是我们需要把间接相连的点连起来(如 1 -> 2 -> 3 , 4 ->2 ->5 ,直接建图,2这个点被使用后4和5就无法联通了) ,用floyd把间接相连的点连起来就好


#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#define maxn 1030#define inf 0x3f3f3f3fusing namespace std;int G[maxn][maxn],vis[maxn],list[maxn],dis[maxn][maxn],n,m;int finds(int u){    for (int i=1;i<=n;i++)    {        if (G[u][i] && !vis[i])        {            vis[i]=1;            if (list[i]==-1 || finds(list[i]))            {                list[i]=u;                return 1;            }        }    }    return 0;}int hungry(){    int sum=0;    for (int i=1;i<=n;i++)    {        memset(vis,0,sizeof(vis));        if (finds(i))         sum++;    }    return sum;}int main(){    int t;    while (scanf("%d%d",&n,&m)!=EOF)    {        if (n==0 && m==0) break;        memset(G,0,sizeof(G));        memset(list,-1,sizeof(list));        memset(dis,inf,sizeof(dis));        for (int i=0;i<m;i++)        {            int u,v;            scanf("%d%d",&u,&v);            G[u][v]=1;        }        for (int k=0;k<n;k++)        {            for (int i=0;i<n;i++)            {                for (int j=0;j<n;j++)                {                    if (G[i][k] && G[k][j])                     G[i][j]=1;                }            }        }        int res=hungry();        printf("%d\n",n-res);    }}


0 0