题意:给你N*M的空地,其中有K块是草坪,问最多有多少块1*2的草坪能铺在空地上。。。
思路:先把空地保存在一个有x,y(行和列)的结构体理;
对能铺上1*2的i,j两点建边,以奇数或偶数(行加列)进行二分匹配。。。。
//HDU 1507
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<cmath>
#include<iostream>
#include <queue>
#include <stack>
#include<algorithm>
#include<set>
using namespace std;
#define INF 1e8
#define inf -0x3f3f3f3f
#define eps 1e-8
#define ll __int64
#define maxn 100+10
#define mol 100007
int vis[maxn],a[maxn][maxn],ans[maxn],map[maxn][maxn],g[maxn];
int k,n,m,sum,num;
struct node
{
int x,y;
}p[maxn*maxn];
int dfs(int id)
{
for(int i=1;i<num;i++)
{
if(!vis[i]&&a[id][i])
{
vis[i]=1;
if(ans[i]==-1||dfs(ans[i]))
{
ans[i]=id;
return 1;
}
}
}
return 0;
}
void match()
{
sum=0;
memset(ans,-1,sizeof(ans));
for(int i=1;i<num;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i)) sum++;
}
}
int main()
{
int i,j;
int t;
while(scanf("%d%d",&n,&m))
{
if(!n&&!m) break;
int u,v;
memset(a,0,sizeof(a));
memset(map,0,sizeof(map));
scanf("%d",&k);
while(k--)
{
scanf("%d%d",&u,&v);
map[u][v]=1;
}
num=1;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(map[i][j]==0)
{
p[num].x =i;
p[num++].y=j;
}
}
}
for(int l=1;l<num;l++)
{
//cout<<i;
for(j=l+1;j<num;j++)
{
if((abs(p[l].x-p[j].x)==1&&p[l].y==p[j].y)||(abs(p[l].y-p[j].y )==1&&p[l].x==p[j].x))
{
if((p[l].x+p[l].y)%2==0)
a[j][l]=1;
else a[l][j]=1;
}
}
}
match();
printf("%d\n",sum);
for(i=0;i<num;i++)
{
if(ans[i]!=-1)
{
printf("(%d,%d)--(%d,%d)\n",p[i].x,p[i].y,p[ans[i]].x,p[ans[i]].y);
}
}
printf("\n");
}
return 0;
}

349

被折叠的 条评论
为什么被折叠?



