hdu4619 Warm up 2 二分匹配 匈牙利算法(再一发)

来源:互联网 发布:广联达算量软件视频 编辑:程序博客网 时间:2024/05/16 05:33
  题意: 有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;}