题意: 有n张横牌,m张竖牌。横牌肯定不相交,竖牌肯定不相交。问 最大的不相交的集合。
题解:先把所有的点中相交的点记录在vector<>中。用匈牙利算法算出最小点覆盖,总点数减去它就是结果。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cctype>
#include<vector>
using namespace std;
struct node{
int x,y;
};
node p1[1005],p2[1005];
vector<int>q[1005];
int n,m,ans;
int link[1005],vit[1005];
bool dfs(int x)
{
for(int y=0;y<q[x].size();y++)
{
int v=q[x][y];
if(!vit[v])
{
vit[v]=1;
if(link[v]==-1||dfs(link[v]))
{
link[v]=x;
return true;
}
}
}
return false;
}
void Search()
{
memset(link,-1,sizeof(link));
for(int i=1;i<=n;i++)
{
memset(vit,0,sizeof(vit));
if(dfs(i))
{
ans++;
}
}
return ;
}
bool judge(int a,int b)
{
if(p1[a].x==p2[b].x&&p1[a].y==p2[b].y)
return true;
if(p1[a].x==p2[b].x&&p1[a].y==p2[b].y+1)
return true;
if(p1[a].x+1==p2[b].x&&p1[a].y==p2[b].y)
return true;
if(p1[a].x+1==p2[b].x&&p1[a].y==p2[b].y+1)
return true;
return false;
}
void add()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(judge(i,j))
q[i].push_back(j);
}
}
int main()
{
while(cin>>n>>m)
{
if(n==0&&m==0)
break;
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
p1[i].x=x,p1[i].y=y;
q[i].clear();
}
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
p2[i].x=x,p2[i].y=y;
}
add();
ans=0;
Search();
ans=n+m-ans;
cout<<ans<<endl;
}
return 0;
}