http://poj.org/problem?id=2226
The problem is same as the minimum vertex cover bipartite graph problem
a cell is covered by the row or the column or both
so you can build the graph by the continuous row or the column
and the Hungarian algorithm is just ok
code of AC:
#include<iostream> #include<cstring> using namespace std; const int N=2e4+10; char S[100][100]; int A[100][100]; int B[100][100]; int head[N],Next[N],ver[N],match[N],v[N]; int tot=0; void add(int x,int y){ ver[++tot]=y; Next[tot]=head[x]; head[x]=tot; } bool dfs(int x){ for(int i=head[x];i;i=Next[i]){ int y=ver[i]; if(v[y]) continue; v[y]=1; if(match[y]==0||dfs(match[y])){ match[y]=x; return 1; } } return 0; } int main(){ int n,m; cin>>n>>m; for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ cin>>S[i][j]; } } int a=0; int b=0; for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ if(S[i][j]=='*'){ if(A[i][j-1]>0) A[i][j]=A[i][j-1]; else A[i][j]=++a; } } } for(int i=1;i<=m;++i){ for(int j=1;j<=n;++j){ if(S[j][i]=='*'){ if(B[j-1][i]>0) B[j][i]=B[j-1][i]; else B[j][i]=++b; } } } int ans=0; for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ if(S[i][j]=='*'){ add(A[i][j],B[i][j]); } } } for(int i=1;i<=a;++i){ memset(v,0,sizeof v); if(dfs(i)) ++ans; } cout<<ans<<endl; }