问题描述
你的汤姆叔叔从他的叔叔那里继承了一块土地。最初它是矩形的。然而,很久以前,他的叔叔决定把这块土地分成一个个小方格。他把一些广场变成池塘。(你不能肯定,因为你没有去过那个地方,但他可能造了很多池塘,现在这片土地可能由几个互不相连的岛屿组成。)
你的汤姆叔叔想卖掉继承来的土地。法律规定,房产只能以相当于你叔叔房产两个正方形大小的矩形地块出售。此外,池塘是不出售的财产。
你叔叔让你帮忙确定他能卖出去的最大数量的房产(剩下的广场将成为休闲公园)。
输入
输入将包括几个测试用例。测试用例的第一行包含两个整数N和M,分别表示土地的行数和列数(1 <= N, M <= 100)。第二行包含一个整数K,表示已经变成池塘的正方形的数量((N x M) - K <= 50)。接下来的K行每一行都包含两个整数X和Y,描述一个正方形变成池塘的位置(1 <= X <= N和1 <= Y <= M),输入的结束由N = M = 0表示。
输出
对于输入中的每个测试用例,您的程序应该首先输出一行,其中包含一个整数p,表示可以出售的属性的最大数量。接下来的p行指定可以同时出售的每对正方形。如果有多个解决方案,任何人都可以接受。在每个测试用例之后都有一个空白行。有关输出格式的说明,请参见下面的示例。
Sample Input
4 4
6
1 1
1 4
2 2
4 1
4 2
4 4
4 3
4
4 2
3 2
2 2
3 1
0 0
Sample Output
4
(1,2)–(1,3)
(2,1)–(3,1)
(2,3)–(3,3)
(2,4)–(3,4)
3
(1,1)–(2,1)
(1,2)–(1,3)
(2,3)–(3,3)
#include <cstdio>
#include <cstring>
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
typedef long long ll;
const int N=1000010;
const int M=400010;
int tot,opo;
bool vis[N],used[1010][1010];
int my[N],mx[N],head[N];
struct Edge{int to,nex;}edge[M];
struct point{int x,y;}p[N];
void add(int from,int to)
{
edge[++tot]=(Edge){to,head[from]};head[from]=tot;
}
bool find_path(int x)
{
for(int i=head[x];i;i=edge[i].nex)
{
int y=edge[i].to;
if(!vis[y])
{
vis[y]=1;
if(!my[y]||find_path(my[y]))
{
my[y]=x;
mx[x]=y;
return 1;
}
}
}
return 0;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m),n||m)
{
m(head,0);
m(used,0);
m(mx,0),m(my,0);
tot=1,opo=0;
int num;
scanf("%d",&num);
while(num--)
{
int a,b;
scanf("%d%d",&a,&b);
used[a][b]=1;
}
for(int i=1;i<=n;i++)
for(int j=(i&1)?1:2;j<=m;j+=2)
{
if(used[i][j])
continue;
p[++opo]=(point){i,j}; //将所有的偶数格子存起来。也就是二分图的左边。
int a=(i-1)*m+j;
if(i>=2&&!used[i-1][j])
add(a,a-m);
if(i<=n-1&&!used[i+1][j])
add(a,a+m);
if(j>=2&&!used[i][j-1])
add(a,a-1);
if(j<=m-1&&!used[i][j+1])
add(a,a+1);
}
int ans=0;
for(int i=1;i<=opo;i++)
{
m(vis,0);
if(find_path((p[i].x-1)*m+p[i].y))
ans++;
}
printf("%d\n",ans);
for(int i=1;i<=opo;i++)
{
int np=mx[(p[i].x-1)*m+p[i].y];
if(np)
{
int nx,ny;
if(!(np%m))
nx=np/m,ny=m;
else
nx=np/m+1,ny=np%m;
printf("(%d,%d)--(%d,%d)\n",p[i].x,p[i].y,nx,ny);
}
}
puts("");
}
}