http://poj.org/problem?id=1325
二分匹配问题 :最小覆盖=最大匹配
这道题凭感觉就知道应该用匈牙利算法求最大匹配,机器A的所有模式为左部顶点,机器B的所有模式为右部顶点,然后A与B之间的每条连线代表一个任务或工作,问题是为什么最大匹配数就是机器要重启的次数。
我们可以这样想,假设现在我们已经找到了一个最大匹配,那么除了由这个最大匹配的边所代表的任务外的任何一个任务,都可以随着最大匹配中某一条匹配边所代表的任务所完成,因为这个任务会和最大匹配中的某个任务至少有一个相同的顶点,即至少有一个相同的模式,但最大匹配的任务之间不会有公共模式,需要重启。
此题还要注意的一点是机器A、B启动时的模式都是0模式,所以若有在0模式可完成的任务就不能考虑在内。
#include<stdio.h> #include<string.h> #define M 300 bool map[M][M]; bool v[M]; int y[M]; int n,m,k; bool SearchPath(int x) { int i; for(i=n;i<n+m;i++) { if(map[x][i]&&!v[i]) { v[i]=true; if(y[i]==-1||SearchPath(y[i])) { y[i]=x; return true; } } } return false; } int MaxMatch() { int i; int ans=0; memset(y,-1,sizeof(y)); for(i=1;i<n;i++) { memset(v,false,sizeof(v)); if(SearchPath(i)) ans++; } return ans; } int main() { int i; while(scanf("%d",&n)&&n) { scanf("%d%d",&m,&k); memset(map,false,sizeof(map)); while(k--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(b&&c) map[b][c+n]=true; } printf("%d\n",MaxMatch()); } return 0; }
POJ 1325
最新推荐文章于 2021-03-18 22:30:38 发布