2014上海邀请赛D 二分匹配匈牙利 行列建图模板
1 #include<stdio.h> 2 #include<string.h> 3 int n,n1,n2,link[1255],y[1255],g[1255][1255],mapl[55][55],mapr[55][55]; 4 char map[55][55]; 5 int dfs(int x) 6 { 7 int i; 8 for (i=n1+1;i<=n1+n2;i++) 9 if (g[x][i]==1&&y[i]==0) 10 { 11 y[i]=1; 12 if (link[i]==0||dfs(link[i])==1) 13 { 14 link[i]=x; 15 return 1; 16 } 17 } 18 return 0; 19 } 20 int main() 21 { 22 int i,j,ans,T,m; 23 scanf("%d",&T); 24 while (T--) 25 { 26 scanf("%d%d",&n,&m); getchar(); 27 for (i=1;i<=n;i++) gets(map[i]); 28 n1=n2=0; 29 memset(mapl,0,sizeof(mapl)); 30 memset(mapr,0,sizeof(mapr)); 31 memset(g,0,sizeof(g)); 32 for (i=1;i<=n;i++) 33 { 34 j=0; 35 while (j<m) 36 { 37 while (j<m&&map[i][j]!='*') j++; 38 if (j<m) n1++; 39 while (j<m&&(map[i][j]!='#')) {mapl[i][j]=n1; j++; } 40 } 41 } 42 for (j=0;j<m;j++) 43 { 44 i=1; 45 while (i<=n) 46 { 47 while (i<=n&&map[i][j]!='*') i++; 48 if (i<=n) n2++; 49 while (i<=n&&map[i][j]!='#') {mapr[i][j]=n2; i++; } 50 } 51 } 52 for (i=1;i<=n;i++) 53 for (j=0;j<m;j++) 54 if (map[i][j]=='*') g[mapl[i][j]][mapr[i][j]+n1]=1; 55 memset(link,0,sizeof(link)); 56 ans=0; 57 for (i=1;i<=n1;i++) 58 { 59 memset(y,0,sizeof(y)); 60 if (dfs(i)==1) ans++; 61 } 62 printf("%d\n",ans); 63 } 64 }
http://acmoj.shu.edu.cn/openjudge/viewproblem.php?coll_id=1&prob_id=353
除此模型二分图还有一些性质:
1.最大匹配+最大独立点集=总点
2.最小顶点覆盖=最大匹配
3.最小路径覆盖=总点-最大匹配