二分匹配
横着的和竖着的可能有重叠部分,有重叠部分的建一条边,求最大匹配即为最小覆盖定点数,再用总的多米诺骨牌数减去,即可求得答案;
#include <iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#define maxn 1005
using namespace std;
int n,m,k;
int linker[maxn];
bool usde[maxn];
vector<int> V[maxn];
bool dfs(int u)
{
int v,i;
for(i=0;i<V[u].size();i++)
{
v=V[u][i];
if(!usde[v])
{
usde[v]=true;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
}
return false;
}
int hungary()
{
int res=0;
int u;
memset(linker,-1,sizeof(linker));
for(u=0;u<n;u++)
{
memset(usde,0,sizeof(usde));
if(dfs(u))
res++;
}
return res;
}
pair<int ,int> p1[maxn];
pair<int ,int> p2[maxn];
int main()
{
int i,j,x,y,x1,y1,x2,y2;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0)
break;
for(i=0;i<n;i++)
{
V[i].clear();
scanf("%d%d",&x,&y);
p1[i]=make_pair(x,y);
}
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
p2[i]=make_pair(x,y);
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
x1=p1[i].first;
y1=p1[i].second;
x2=p2[j].first;
y2=p2[j].second;
if(x1==x2&&y1==y2||x1+1==x2&&y1==y2||x1==x2&&y1==y2+1||x1+1==x2&&y1==y2+1)
V[i].push_back(j);
}
}
printf("%d\n",n+m-hungary());
}
return 0;
}