两个集合
分别是按行和列凑成的点的集合
如图
1000
0000
2203
0004
1000
0000
1203
0003
两个集合构成的边,求该图的最大二分匹配
#include<bits/stdc++.h> using namespace std; bool edge[3000][3000]; char mapp[100][100]; int num1[100][100],num2[100][100],link[3000]; bool vis[3000]; int k1,k2,cnt; bool dfs(int x) { for(int y=1;y<k2;y++) if(edge[x][y]&&!vis[y]) { vis[y]=1; if(link[y]==0 || dfs(link[y])) { link[y]=x; return true; } } return false; } void search() { memset(link,0,sizeof(link)); for(int x=1;x<k1;x++) { memset(vis,0,sizeof(vis)); if(dfs(x)) cnt++; } } int main() { int T; scanf("%d",&T); while(T--){ int N,M; scanf("%d%d",&M,&N); memset(edge,0,sizeof(edge)); memset(num1,0,sizeof(num1)); memset(num2,0,sizeof(num2)); memset(mapp,0,sizeof(mapp)); for(int i=1;i<=M;i++) for(int j=1;j<=N;j++) cin>>mapp[i][j]; k1=k2=1; for(int i=1;i<=M;i++){ for(int j=1;j<=N;j++) { if(mapp[i][j]=='#') k1++; if(mapp[i][j]=='*') num1[i][j]=k1; } k1++; } for(int i=1;i<=N;i++){ for(int j=1;j<=M;j++) { if(mapp[j][i]=='#') k2++; if(mapp[j][i]=='*') num2[j][i]=k2; } k2++; } for(int i=1;i<=M;i++) for(int j=1;j<=N;j++) edge[ num1[i][j] ][ num2[i][j] ]=1; cnt=0; search(); printf("%d\n",cnt); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-17 13:44:06