题意:输入一个地图,*是草坪 # 是墙 o是空地。机器人只能放在空地上,且两个同行或者同列的机器人中间必须有墙,问最多可以放多少个机器人。
书上给出:......将行视为x , 列视为 y. 求 x 与 y 这个2分图之间的最大匹配。
#include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set> #include <queue> #include <stack> #include<math.h> using namespace std; int numx;int numy; const int maxn=51; int link[maxn*maxn]; int xx[maxn*maxn],yy[maxn*maxn]; int x[maxn][maxn]; int y[maxn][maxn]; int used[maxn*maxn]; int g[maxn*maxn][maxn*maxn]; int dfs(int x) { for(int i=1;i<=numy;i++){ if(g[x][i]&&!used[i]){ used[i]=1; if(link[i]==-1||dfs(link[i])){ link[i]=x; return 1; } } } return 0; } void solve() { int ans=0; for(int i=1;i<=numx;i++){ memset(used,0,sizeof(used)); if(dfs(i)) ans++; } cout<<ans<<endl; } int main() { char str[maxn][maxn]; int Icase; int n,m; scanf("%d",&Icase); int k=0; while(Icase--){ memset(link,-1,sizeof(link)); k++; memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); memset(g,0,sizeof(g)); scanf("%d%d",&m,&n); for(int i=0;i<m;i++) scanf("%s",str[i]); numx=0;numy=0; for(int i=0;i<m;i++){ int flag=0; for(int j=0;j<n;j++){ if(str[i][j]==‘o‘){ if(!flag) numx++; x[i][j]=numx;flag=1; } else if(str[i][j]==‘#‘) flag=0; } } for(int j=0;j<n;j++){ int flag=0; for(int i=0;i<m;i++){ if(str[i][j]==‘o‘){ if(!flag) numy++; y[i][j]=numy;flag=1; } else if(str[i][j]==‘#‘) flag=0; } } for(int i=0;i<m;i++) for(int j=0;j<n;j++) if(x[i][j]) g[x[i][j]][y[i][j]]=1; printf("Case :%d\n",k); solve(); } return 0; }
zoj1654二分图
时间: 2024-10-22 23:35:36