Description
Input
The first line of each case are 2 integers: n(1 <= n <= 1000), m(1 <= m <= 1000), indicating the number of horizontal and vertical dominoes.
Then n lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x + 1, y).
Then m lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x, y + 1).
Input ends with n = 0 and m = 0.
Output
Sample Input
2 3 0 0 0 3 0 1 1 1 1 3 4 5 0 1 0 2 3 1 2 2 0 0 1 0 2 0 4 1 3 2 0 0
Sample Output
4 6
这道题的题意是给你一些1*2的骨牌,骨牌可能是垂直放置所占坐标是(x,y).(x,y+1) , 也可能是平行放置所占坐标是(x,y)。(x+1,y),骨牌不会重合,但是骨牌的坐标可能重合,叫你将这些坐标重合的骨牌去掉,问留下骨牌数最多为多少???
这道题就是一道最大独立集的题目,这里我们要建图,以横起的和竖起的骨牌建图,就是吧坐标重合的那些点相连,最后总点数减去最大二分匹配数
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
#define ll long long
#define nn 2005
int ma[nn][nn];
int use[nn];
int id[nn];
int n,m;
int dfs(int x)
{
int i;
for(i=1;i<=m+n;i++)
{
if(use[i]==false&&ma[x][i]==1)
{
use[i]=true;
if(id[i]==-1||dfs(id[i]))
{
id[i]=x;
return true;
}
}
}
return false;
}
int cnt;
void fin()
{
memset(id,-1,sizeof(id));
int i;
cnt=0;
for(i=1;i<=n+m;i++)
{
memset(use,false,sizeof(use));
if(dfs(i))
cnt++;
}
printf("%d\n",(n+m)-cnt);
}
struct node
{
int x,y;
int num;
}point[nn];
int main()
{
int i,j;
while(scanf("%d %d",&n,&m)&&m+n)
{
memset(ma,0,sizeof(ma));
for(i=1;i<=n+m;i++)
{
scanf("%d %d",&point[i].x,&point[i].y);
point[i].num=i;
}
for(i=1;i<=n;i++)
{
for(j=n+1;j<=m+n;j++)
{
if( ((point[i].x==point[j].x)&&(point[i].y==point[j].y)) || ((point[i].x+1==point[j].x)&&(point[i].y==point[j].y)) ||((point[i].x+1==point[j].x)&&(point[i].y==point[j].y+1)) || ((point[i].x==point[j].x)&&(point[i].y==point[j].y+1)) )
{
ma[point[i].num][point[j].num]=1;
}
}
}
fin();
}
}