题意:一个有 N 个节点的有向无环图, 已知有 M 条边,问最少放多少机器人可以使得图中任何一点都至少可以被其中一个机器人达到。
分析: 最小路径覆盖。 因为可以经过一些点到达另一些顶点,所以需要传递闭包将每个点可达的顶点都连上边,然后求最小路径覆盖。
最小路径覆盖 = 总权 - 最大匹配
#include<stdio.h> #include<string.h> #define clr(x)memset(x,0,sizeof(x)) int g[505][505]; int link[505]; int v[505]; int n; int find(int x) { int i; for(i=1;i<=n;i++) { if(g[x][i]&&(!v[i])) { v[i]=1; if(link[i]==0||find(link[i])) { link[i]=x; return 1; } } } return 0; } int main() { int i,j,k,m,res,a,b; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) break; clr(g); while(m--) { scanf("%d%d",&a,&b); g[a][b]=1; } for(k=1;k<=n;k++) for(i=1;i<=n;i++) if(g[i][k]) for(j=1;j<=n;j++) g[i][j]=g[i][j]||(g[i][k]&&g[k][j]); clr(link); res=0; for(i=1;i<=n;i++) { clr(v); if(find(i)) res++; } printf("%d\n",n-res); } return 0; }