HDU 3829 Cat VS Dog 2011 Multi-University Training Contest 1 - Host by HNU

来源:互联网 发布:淘宝买原味胖次 编辑:程序博客网 时间:2024/05/17 01:48

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3829


题意:有一群人,他们要么喜欢狗讨厌猫,要么喜欢猫讨厌狗,在自己喜欢的动物C留下且自己讨厌的动物D他们会happy,求管理员最多让多少人开心

题解:最大独立点集,拆点转换为最大流问题,当两个人的喜好有矛盾(既自己喜欢的别人讨厌或讨厌的的被人喜欢)建边,为无向图(既A和B有矛盾必然有B和A有矛盾),所以最大独立集=n-最大匹配/2;

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#include<vector>#include<stack>using namespace std;int n,m,p;struct person{    bool cat;    int like;    int hate;}pe[550];int link[550],map[550][550],vis[550];void init(){    memset(map,0,sizeof(map));    for(int i=0;i<p;i++)    for(int j=i+1;j<p;j++)    {        if(pe[i].cat==!pe[j].cat)          //判断i,j是否有矛盾,有矛盾则建双向边        {            if(pe[i].like==pe[j].hate||pe[i].hate==pe[j].like)            {                map[i][j]=map[j][i]=1;            }        }    }}int can(int x){    for(int j=0;j<p;j++)    {        if(!vis[j]&&map[x][j])        {            vis[j]=1;            if(link[j]==-1||can(link[j]))            {                link[j]=x;                return 1;            }        }    }    return 0;}void solve()                //二分匹配{   memset(link,-1,sizeof(link));   int num=0;   for(int i=0;i<p;i++)   {       memset(vis,0,sizeof(vis));       if(can(i))       num++;   }   printf("%d\n",p-num/2);}int main(){    while(scanf("%d%d%d",&n,&m,&p)!=EOF)    {        char ch1,ch2;        int aa,bb;        for(int i=0;i<p;i++)        {            cin>>ch1>>aa>>ch2>>bb;            if(ch1=='C')            {                pe[i].cat=true;                pe[i].like=aa;                pe[i].hate=bb;            }            else            {                pe[i].cat=false;                pe[i].like=aa;                pe[i].hate=bb;            }        }        init();        solve();    }return 0;}


原创粉丝点击