HDU-3829 Cat VS Dog

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.
        
 

题目大意:

     有p个小朋友参观动物园,动物园里面有两种动物,分别为猫和狗。规定一个小朋友喜欢猫就讨厌狗,喜欢狗就讨厌猫。现在管理员要移走0一些动物,当然,移走也是有条件的。比如一个小朋友喜欢猫3,讨厌狗4.那么移走狗4,这个小朋友就会非常开心。同样,如果移走猫3,小朋友就会很不高兴。现在问怎么样才能使开心的小朋友的人数最多。

解题思路:

可以在小朋友之间建边,当然,是在矛盾关系的小朋友之间建边。矛盾有2种情况:我喜欢的是前面讨厌的,我讨厌的是前面喜欢的。然后就可以套用结论:二分图最大独立集=定点数-二分图最大匹配。

但是在做的过程中,我又理解了一点二分图的性质:

因为小朋友与小朋友是没有差别的,而二分图必须要求是2个集合,现在只有一个小朋友的集合,那么我们可以用到拆点的思想,把每个小朋友拆成2个小朋友,这样在求最大匹配的时候除以2就可以了。(相当于匹配了2次~。:如果你拆点后,就必须建立双向边,比如1和2之间有矛盾,你不能只建立1-2矛盾边,必须还建立2-1矛盾边。

代码:

#include<stdio.h>
#include<string.h>
int map[1010][1010];
int match[1010];
int book[1010];
int n,m,k;

int dfs(int u)
{
	int i;
	for(i=1;i<=k;i++)
	{
		if(book[i]==0&&map[u][i]==1)
		{
			book[i]=1;
			if(match[i]==0||dfs(match[i]))
			{
				match[i]=u; 
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	int i,j,sum,s;
	char s1[510][20],s2[510][20];
	while(scanf("%d%d%d",&n,&m,&k)!=EOF)
	{
		memset(map,0,sizeof(map));
		memset(match,0,sizeof(match));
		for(i=1;i<=k;i++)
			scanf("%s%s",s1[i],s2[i]);
		for(i=1;i<=k;i++)
        	for(j=i+1;j<=k;j++)
	       	{
	        	if(strcmp(s1[i],s2[j])==0||strcmp(s1[j],s2[i])==0)
	        	{
	        		map[i][j]=1;
	        		map[j][i]=1;
				}	
	    	}
	    sum=0;
		for(i=1;i<=k;i++)
		{
			memset(book,0,sizeof(book));
			if(dfs(i))
				sum++;
		}
		printf("%d\n",k-sum/2); 
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/hello_cmy/article/details/81589064
Dog
cat