1. 程式人生 > >hdu4619 Warm up 2 二分圖匹配匈牙利演算法

hdu4619 Warm up 2 二分圖匹配匈牙利演算法

今天晚上學了一下神奇的匈牙利演算法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);
    }
}