POJ 2226 Kőnig's Theorem

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;
}

猜你喜欢

转载自blog.csdn.net/gipsy_danger/article/details/80323413