Hdu 1507(二分图匹配)

Hdu 1507

(1)题意:

选取两个连续的空地作为一个单元,其中给出一些标记的池塘,池塘不能被选择,求出最多可以选择多少个单元的地方。

每个地方用两个坐标来表示。

(2)思路:

将图中所有能够选取的空地按照(i+j)%2==1,和(i+j)%2==0,分为两部分,

如果这两部分相邻,这两个个点之间有一条边。

然后用二分图求出这张图的最大匹配就是最多的连续的面积。

(3)代码:

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

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/92387811