hdu 4619 Warm up 2 ( 二分图最大匹配 )

题目:Warm up 2

题意:有横竖两种方式放着的多米诺骨牌,相同方向的不可能重叠,但是横放和竖放

            的牌可能重叠。移走重叠的牌使剩下的牌最多。

分析:二分图匹配:最大独立集=顶点数-最大匹配数

            横放的为一个点集,竖放的为一个点集。

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

struct node
{
    int x1,y1;
    int x2,y2;
}hori[1010],ver[1010];
int g[1010][1010];
int vis[1010];
int match[1010];
int m,n;

bool dfs(int u)
{
    int i;
    for(i=0;i<m;i++)
    {
        if(g[u][i] && !vis[i])
        {
            vis[i]=true;
            if(match[i]==-1||dfs(match[i]))
            {
                match[i]=u;
                return true;
            }
        }
    }
    return false;
}
int main()
{
    int i,j,cnt,ans;
    while(scanf("%d%d",&n,&m)&&n&&m)
    {
        memset(match,-1,sizeof(match));
        memset(g,0,sizeof(g));
        cnt=0;
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&hori[i].x1,&hori[i].y1);
            hori[i].x2=hori[i].x1+1;
            hori[i].y2=hori[i].y1;
            cnt++;
        }
        for(i=0;i<m;i++)
        {
            scanf("%d%d",&ver[i].x1,&ver[i].y1);
            ver[i].x2=ver[i].x1;
            ver[i].y2=ver[i].y1+1;
            cnt++;
        }
        //printf("cnt=%d
",cnt);
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(hori[i].x1==ver[j].x1 && hori[i].y1==ver[j].y1)
                    g[i][j]=true;
                else if(hori[i].x2==ver[j].x1 && hori[i].y2==ver[j].y1)
                    g[i][j]=true;
                else if(hori[i].x1==ver[j].x2 && hori[i].y1==ver[j].y2)
                    g[i][j]=true;
                else if(hori[i].x2==ver[j].x2 && hori[i].y2==ver[j].y2)
                    g[i][j]=true;
            }
        }
        ans=0;
        for(i=0;i<n;i++)
        {
            memset(vis,0,sizeof(vis));
            if(dfs(i)) ans++;
        }
        //printf("ans=%d
",ans);
        printf("%d
",cnt-ans);
    }
    return 0;
}


原文地址:https://www.cnblogs.com/keanuyaoo/p/3283265.html