1. 程式人生 > >poj2226Muddy Fields——二分圖匹配

poj2226Muddy Fields——二分圖匹配

bsp pre str namespace sca include ring pan ()

題目: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; }

poj2226Muddy Fields——二分圖匹配