题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4619
今天晚上学了一下神奇的匈牙利算法QwQ
题的大意是给出许多1*2和2*1的块的坐标,保证1*2的块之间、2*1的块之间没有重叠,问最多有几个块互不重叠。
首先建立一个二分图,如果两个块重叠就在它们所代表的点之间画一条边,然后用匈牙利算法求出二分图的最大匹配,答案就是点的总数-最大匹配数。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<set>
#include<cmath>
using namespace std;
int used[1005],s[1005],n,m,vis[105][105],line[1005][1005];
bool findd(int x)
{
for(int i=1;i<=m;i++)
{
if(line[x][i]&&!used[i])
{
used[i]=1;
if(s[i]==0||findd(s[i]))
{
s[i]=x;
return 1;
}
}
}
return 0;
}
int main()
{
while(scanf("%d %d",&n,&m)&&(n||m))
{
int hx[1005],hy[1005],sx[1005],sy[1005],ans=0;
memset(s,0,sizeof(s));
memset(line,0,sizeof(line));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
scanf("%d %d",&hx[i],&hy[i]);
vis[hx[i]][hy[i]]=i;
vis[hx[i]+1][hy[i]]=i;
}
for(int i=1;i<=m;i++)
{
scanf("%d %d",&sx[i],&sy[i]);
if(vis[sx[i]][sy[i]])
{
line[vis[sx[i]][sy[i]]][i]=1;
}
if(vis[sx[i]][sy[i]+1])
{
line[vis[sx[i]][sy[i]+1]][i]=1;
}
}
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof(used));
if(findd(i))
{
ans++;
}
}
printf("%d\n",n+m-ans);
}
}