ZOJ 1364 Machine Schedule (POJ 1325) (最小点覆盖数==最大匹配数)

 

基础题,但是这个证明值得膜拜,orz个先……

求二分图的最小点覆盖数

用最少的点将所有的边覆盖,这个覆盖数等于最大匹配数M;

下面是LRJ的证明,很好很强大:

①M个是足够的,只需要让他们覆盖最大的匹配的M条边,则其他边一定被覆盖

(如果有边e不被覆盖,把e加入后得到一个更大的匹配)

②M个是必需的,仅考虑形成最大匹配的M条边,由于两两无公共点,因此至少

需要M个点才能把它们覆盖;

(摘自:http://hi.baidu.com/rain_bow_joy/blog/item/51ced908dcb733a52eddd4cb.html)

 

 

 

建图:机器A的模式 i 和机器B的模式 j 可完成同一个工作,就在之间加权值1的边,代表工作

代码:

 

#include<stdio.h> #include<string.h> #define N 110 int n,m,k,map[N][N],vis[N],match[N]; void getmap() { int i,a,b,c; memset(map,0,sizeof(map)); for(i=0;i<k;i++) { scanf("%d%d%d",&a,&b,&c); if(!b||!c)continue; //0状态能完成的工作,不需要重启机器,所以不用参与构图 map[b][c]=1; } } int dfs(int x) { int i; for(i=0;i<m;i++) if(map[x][i] && !vis[i]) { vis[i]=1; if( !match[i] || dfs(match[i]) ) { match[i]=x; return 1; } } return 0; } int main() { int cnt,i; while(scanf("%d",&n),n) { scanf("%d%d",&m,&k); getmap(); memset(match,0,sizeof(match)); for(cnt=0,i=0;i<n;i++) { memset(vis,0,sizeof(vis)); if( dfs(i) ) cnt++; } printf("%d/n",cnt); } return 0; } 

你可能感兴趣的:(ZOJ 1364 Machine Schedule (POJ 1325) (最小点覆盖数==最大匹配数))