hdu 4619 Warm up 2

来源:互联网 发布:java微信内h5调起支付 编辑:程序博客网 时间:2024/05/21 21:42
题意分析: 水平N牌 ,垂直M牌 ,水平相互独立(即不想交) ,垂直也是如此。 
          可以看出这是一个二分图。
          但是水平的牌和垂直的会相交,求最少踢出去几张牌,使得剩下的牌都不相交 。
          那么把水平和垂直相交的牌连边,求出最大匹配数,把这些匹配的边切断,剩下的牌就相互不交了。也就是最大独立点。
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>#include <vector>#define maxn 1010using namespace std;int N,M;struct node{    int x,y;} p1[1010],p2[1010];int lef[maxn];bool T[maxn];int cnt;vector<int> g[1010];bool match(int u){    int i,j;    for(i=0; i<g[u].size(); i++)    {        int v = g[u][i];        if (!T[v])        {            T[v] = true;            if (lef[v] == -1 || match(lef[v]))            {                lef[v] = u;                return true;            }        }    }    return false;}int solve(){    memset(lef, -1, sizeof(lef));    int ans = 0;    int u;    for(u = 1; u <= N; u++)    {        memset(T, 0, sizeof(T));        if(match(u))        {            ans++;        }    }    return ans;}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 build(){    int i,j;    for(i=1; i<=N; i++)    {        for(j=1; j<=M; j++)        {            if(judge(i,j))            {                g[i].push_back(j);            }        }    }}int main(){    //  freopen("input.txt","r",stdin);    int i,j;    while(scanf("%d %d",&N,&M)==2&&N+M)    {        for(i=1; i<=N; i++)        {            scanf("%d %d",&p1[i].x,&p1[i].y);            g[i].clear();        }        for(i=1; i<=M; i++)        {            scanf("%d %d",&p2[i].x,&p2[i].y);        }        build();        int temp=solve();        printf("%d\n",N+M-temp);    }    return 0;}


原创粉丝点击