您的位置:首页 > 其它

HDU3829 Cat VS Dog(二分图最大独立集)

2017-11-16 21:26 465 查看

Problem Description

The zoo have N cats and M dogs, today there are P children visiting

the zoo, each child has a like-animal and a dislike-animal, if the

child’s like-animal is a cat, then his/hers dislike-animal must be a

dog, and vice versa. Now the zoo administrator is removing some

animals, if one child’s like-animal is not removed and his/hers

dislike-animal is removed, he/she will be happy. So the administrator

wants to know which animals he should remove to make maximum number of

happy children.

Input

The input file contains multiple test cases, for each case, the first

line contains three integers N <= 100, M <= 100 and P <= 500. Next P

lines, each line contains a child’s like-animal and dislike-animal, C

for cat and D for dog. (See sample for details)

Output

For each case, output a single integer: the maximum number of happy

children.

Sample Input

1 1 2
C1 D1
D1 C1

1 2 4
C1 D1
C1 D1
C1 D2
D2 C1


Sample Output

1
3


Hint

Case 2: Remove D1 and D2, that makes child 1, 2, 3 happy

思路

动物园有N只猫,M只狗,P个小孩。每个小孩都有自己喜欢的动物和讨厌的动物,如果他喜欢狗,那么就讨厌猫, 如果他讨厌狗,那么他就喜欢猫。某个小孩能开心,当且仅当他喜欢的动物留在动物园和讨厌的动物不在动物园里面。 现让管理员通过带走某些动物,问最多能使多少个孩子开心。

我们对有冲突的人建立双向边,然后求出他们的最大匹配,然后用顶点数n减去有冲突的最大匹配就是答案

为了让尽量多的孩子开心,那么要选出一个最大的集合里面的点没有矛盾,因此根据孩子之间有矛盾建边,然后选出最大独立集即可。

最大独立集=总结点-最大匹配数。因为拿整个二分图来求最大匹配,而不是具体分出X,Y二部分来求,因此最后的匹配数要除以2.

代码

#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<iostream>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define mod 10000007
#define debug() puts("what the fuck!!!")
#define ll long long
using namespace std;
const int N=500+20;
int vis
,match
,e

,n,m,p;
pair<string,string>per
;
int dfs(int u)
{
for(int i=1; i<=p; i++)
{
if(e[u][i]&&!vis[i])
{
vis[i]=1;
if(!match[i]||dfs(match[i]))
{
match[i]=u;
return 1;
}
}
}
return 0;
}
int query()
{
mem(match,0);
int sum=0;
for(int i=1; i<=p; i++)
{
mem(vis,0);
if(dfs(i))sum++;
}
return sum;
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&p))
{

ec43
mem(e,0);
for(int i=1; i<=p; i++)
{
cin>>per[i].first>>per[i].second;
for(int j=1; j<i; j++)
if((per[i].first==per[j].second)||(per[i].second==per[j].first))
e[i][j]=e[j][i]=1;
}
printf("%d\n",p-query()/2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: