标签:ios int nbsp names 二分 ems ext iostream set
题目:http://poj.org/problem?id=2226
把行连通块作为左部点,列连通块作为右部点,行列连通块有相交的格子就连边;
则问题转化为求最小点覆盖,即最大匹配。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int const MAXN=50005; int R,C,bh[55][55][55][55],col[55][55],pre[MAXN],ans,cnt,head[MAXN],ct,bj; char c[55][55],dc[55]; bool vis[MAXN]; struct N{ int to,next; N(int t=0,int n=0):to(t),next(n) {} }edge[MAXN*50]; void add(int x,int y) {edge[++ct]=N(y,head[x]);head[x]=ct;} bool dfs(int x) { for(int i=head[x];i;i=edge[i].next) { int u=edge[i].to; if(!vis[u]) { vis[u]=1; if(!pre[u]||dfs(pre[u])) {pre[u]=x;return 1;} } } return 0; } int main() { scanf("%d%d",&R,&C); for(int i=1;i<=R;i++) { cin>>dc; for(int j=1;j<=C;j++) c[i][j]=dc[j-1]; } for(int i=1;i<=R;i++) { int j=1; while(j<=C) { if(c[i][j]==‘.‘){j++;continue;} cnt++; while(c[i][j]==‘*‘)col[i][j]=cnt,j++; } } bj=cnt; for(int j=1;j<=C;j++) { int i=1; while(i<=R) { if(c[i][j]==‘.‘){i++;continue;} cnt++; while(c[i][j]==‘*‘) { if(col[i][j])add(col[i][j],cnt); i++; } } } for(int i=1;i<=bj;i++) { memset(vis,0,sizeof vis); if(dfs(i))ans++; } printf("%d",ans); return 0; }
标签:ios int nbsp names 二分 ems ext iostream set
原文地址:https://www.cnblogs.com/Zinn/p/8868305.html