题目链接: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 0x3f3f3f3f using 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); } }