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; }