Hdu 1507 (bipartite graph matching)

Hdu 1507

 

(1) meaning of the questions:

Selecting two consecutive space as a unit, which give some labeled pond, the pond can not be selected, to obtain a maximum number of local units may be selected.

Every place is represented by two coordinates.

 

(2) ideas:

FIG all the space can be selected according to (i + j)% 2 == 1, and (i + j)% 2 == 0, divided into two parts,

If the two adjacent portions, there is an edge between these two points all.

And then find the maximum matching bipartite graph of this figure is the largest continuous area.

 

(3) Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 1e4+10;
int head[maxn],vis[maxn],pre[maxn],tot,n,m,k,mp[120][120],len,bj[maxn];
struct Node{
	int v,nxt;
}cur[maxn<<2];
int dx[4] = {0,0,-1,1};
int dy[4] = {1,-1,0,0};
vector <int> v1,v2;
void Init(){
	memset(head,-1,sizeof(head));
	tot = 0;
}
void Add(int x,int y){
	cur[tot].v = y;
	cur[tot].nxt = head[x];
	head[x] = tot++;
}
int dfs(int x){
	for(int i=head[x];i!=-1;i=cur[i].nxt){
		int y = cur[i].v;
		if(vis[y]==0){
			vis[y] = 1;
			if(pre[y]==-1||dfs(pre[y])){
				pre[y] = x;
				return true;
			}
		}
	}
	return false;
}
int fun(){
	memset(bj,0,sizeof(bj));
	memset(pre,-1,sizeof(pre));
	len = v1.size();
	int ans = 0;
	for(int i=0;i<len;i++){
		memset(vis,0,sizeof(vis));
		if(dfs(v1[i])){
			bj[v1[i]] = 1;ans++;
		}
	}
	return ans;
}
int main(void){
	while(~scanf("%d%d",&n,&m)&&(n+m)){
		scanf("%d",&k);
		v1.clear();
		v2.clear();
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++) mp[i][j] = 0;
		Init();
		for(int i=0;i<k;i++){
			int x,y;scanf("%d%d",&x,&y);
			mp[x][y] = 1;
		}
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
			if(mp[i][j]==0&&(i+j)%2==1){
				int x = (i-1)*m+j;
				v1.push_back(x);
				for(int k=0;k<4;k++){
					int ti = i+dx[k];
					int tj = j+dy[k];
					if(ti>=1&&ti<=n&&tj>=1&&tj<=m&&mp[ti][tj]==0){
						int y = (ti-1)*m+tj;
						Add(x,y);
					}
				}
			}
			else if(mp[i][j]==0&&(i+j)%2==0) v2.push_back((i-1)*m+j);
		int ans = fun();
		printf("%d\n",ans);
		int ll = v2.size();
		for(int i=0;i<ll;i++)
		if(bj[pre[v2[i]]]==1){
			int x1 = pre[v2[i]]/m+1,y1 = pre[v2[i]]%m;
			if(y1==0){
				y1 = m;x1--;
			}
			int x2 = v2[i]/m+1,y2 = v2[i]%m;
			if(y2==0){
				y2 = m;x2--;
			}
			printf("(%d,%d)--(%d,%d)\n",x1,y1,x2,y2);
		}
		printf("\n");
	}
	return 0;
}

 

Guess you like

Origin blog.csdn.net/qq_41829060/article/details/92387811