hdu 4619

来源:互联网 发布:c 可视化编程 编辑:程序博客网 时间:2024/06/05 18:30

二分匹配

横着的和竖着的可能有重叠部分,有重叠部分的建一条边,求最大匹配即为最小覆盖定点数,再用总的多米诺骨牌数减去,即可求得答案;





#include <iostream>#include<cstdio>#include<cstring>#include<map>#include<vector>#define maxn 1005using 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;}