hdu 3829 Cat VS Dog 最大点独立集

可以想到是个二分图,x节点是喜欢狗的,y节点是喜欢猫的,在有冲突的节点间连边(x节点间不会有冲突,y节点间不会有冲突,所以是二分图),即若x[ i ]喜欢的是y[ j ]讨厌的,或x[ i ]讨厌的是y[ j ]喜欢的,那么g[ i ][ j ] = g[ j ][ i ] = 1,则该二分图的最大点独立集除以2就是所求,除以2的原因是求了两次。

#include <stdio.h>
#include <string.h>
#define maxn 510
int nx,ny;
int g[maxn][maxn],ans,sx[maxn],sy[maxn];
int cx[maxn],cy[maxn];
int path(int u)
{
    sx[u]=1;
    int v;
    for(v=1;v<=ny;v++)
    {
        if(g[u][v]>0&&!sy[v])
        {
            sy[v]=1;
            if(!cy[v]||path(cy[v]))
            {
                cx[u]=v;cy[v]=u;
                return 1;
            }
        }
    }
    return 0;
}
void solve()
{
    ans=0;
    int i;
    memset(cx,0,sizeof(cx));
    memset(cy,0,sizeof(cy));
    for(i=1;i<=nx;i++)
    {
        if(!cx[i])
        {
            memset(sx,0,sizeof(sx));
            memset(sy,0,sizeof(sy));
            ans+=path(i);
        }
    }
}
struct Node
{
    int l;
    int d;
}node[maxn];
int main()
{
    int i,j;
    int n;//cat
    int m;//dog
    int p;
    while(scanf("%d%d%d",&n,&m,&p)!=EOF)
    {
        memset(g,0,sizeof(g));
        char d;
        int id;
        for(i=1;i<=p;i++)
        {
            getchar();
            scanf("%c%d",&d,&id);
            if(d=='D') node[i].l=id;
            else if(d=='C')  node[i].l=m+id;
            getchar();
            scanf("%c%d",&d,&id);
            if(d=='D') node[i].d=id;
            else if(d=='C')  node[i].d=m+id;
        }
        for(i=1;i<=p;i++)
            for(j=1;j<=p;j++)
            {
                if(i==j) continue;
                if(node[i].l==node[j].d||node[i].d==node[j].l)
                    g[i][j]=g[j][i]=1;
            }
        nx=ny=p;
        solve();
        printf("%d\n",(2*p-ans)/2);
    }
    return 0;
}


 

 

posted @ 2014-04-17 17:19  贝尔摩德  阅读(136)  评论(0编辑  收藏  举报