二分图匹配:
分别按行和列把图展开,hungary二分图匹配。。。。
样例: 4 4 *ooo o### **#* ooo* 按行展开。。。。 *ooo o#oo oo#o ooo# **#o ooo* ooo* 再按列展开。。。 7 * 8 *ooooooo oooooooo oooooooo oooooooo *o*ooooo ooooooo* ooooooo* 匹配结果3
2 4 4 *ooo o### **#* ooo* 4 4 #*** *#** **#* ooo#
3 5
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=2600; char mp[55][55]; char hang[maxn][maxn]; char lie[maxn][maxn]; int n,m; int nn,mm; void getHang() { nn=0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(mp[i][j]=='o') { hang[nn][j]='o'; } else if(mp[i][j]=='*') { hang[nn][j]='*'; } else if(mp[i][j]=='#') { hang[nn][j]='#'; for(int k=j+1;k<m;k++) { hang[nn][k]='o'; } if(j!=m-1) { nn++; for(int k=0;k<=j;k++) { hang[nn][k]='o'; } } } } nn++; } /*********************debug*********************** cout<<" debug hang \n"; for(int i=0;i<nn;i++) { printf("%s\n",hang[i]); } *********************debug***********************/ } void getLie() { mm=0; for(int i=0;i<m;i++) { for(int j=0;j<nn;j++) { if(hang[j][i]=='*') { lie[j][mm]='*'; } else if(hang[j][i]=='o') { lie[j][mm]='o'; } else if(hang[j][i]=='#') { for(int k=j;k<nn;k++) { lie[k][mm]='o'; } if(j!=nn-1) { mm++; for(int k=0;k<=j;k++) { lie[k][mm]='o'; } } } } mm++; } /**************debug lie******************* cout<<"debug lie\n"; cout<<nn<<" * "<<mm<<endl; for(int i=0;i<nn;i++) { for(int j=0;j<mm;j++) { printf("%c",lie[i][j]); if(j==mm-1) putchar(10); } } **************debug lie*******************/ } struct Edge { int to,next; }edge[maxn*maxn]; int Adj[maxn],Size; void init() { memset(Adj,-1,sizeof(Adj)); Size=0; } void add_edge(int u,int v) { edge[Size].to=v; edge[Size].next=Adj[u]; Adj[u]=Size++; } int linker[maxn]; bool used[maxn]; bool dfs(int u) { for(int i=Adj[u];~i;i=edge[i].next) { int v=edge[i].to; if(!used[v]) { used[v]=true; if(linker[v]==-1||dfs(linker[v])) { linker[v]=u; return true; } } } return false; } int hungary() { int res=0; memset(linker,-1,sizeof(linker)); for(int u=0;u<nn;u++) { memset(used,false,sizeof(used)); if(dfs(u)) res++; } return res; } int main() { int T_T; scanf("%d",&T_T); while(T_T--) { memset(mp,0,sizeof(mp)); memset(hang,0,sizeof(hang)); memset(lie,0,sizeof(lie)); init(); scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%s",mp[i]); getHang(); getLie(); /// build graph for(int i=0;i<nn;i++) { for(int j=0;j<mm;j++) { if(lie[i][j]=='*') { add_edge(i,j); } } } printf("%d\n",hungary()); } return 0; }