HDOJ3829 Cat VS Dog[匈牙利]

Cat VS Dog

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others)
Total Submission(s): 1728    Accepted Submission(s): 581


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.
 
Source
 
Recommend
xubiao

转自:http://blog.sina.com.cn/s/blog_68629c7701012lcn.html

大致题意:

    一个动物园里面有n只猫,m只狗(吃饱撑的在动物园养猫狗……擦)。还有P个小孩,每个小孩都会喜欢某种动物中的一只,讨厌另一种动物中的一只(比如喜欢猫1,讨厌狗2)。现在动物园打算和谐掉一些动物。规定对于一个小孩,如果他讨厌的那只动物被和谐掉,喜欢的那只动物被保留的话,这个小孩就会很爽。求最多可以让多少个小孩爽。
 
大致思路:
    做的很囧,想到了用二分图解决,就是想不出如何来构造这个模型,后来看题解过的~~大牛们切勿bs啊。可以这么想,首先把喜欢狗讨厌猫和喜欢猫讨厌狗的人分别加入两个集合X,Y中。如果X集合中的第i人和Y集合中的第j人有矛盾(第i个人喜欢的动物被第j个人讨厌,第i个人讨厌的东西却被第j个人喜欢,也就是这两个人之间最多只能有一个人被爽到!!),则连接i,j。求出这个二分图的最大独立集就是答案。
 
 
code:
 1 #include <iostream>   
 2 #include <iomanip>   
 3 #include <fstream>   
 4 #include <sstream>   
 5 #include <algorithm>   
 6 #include <string>   
 7 #include <set>   
 8 #include <utility>   
 9 #include <queue>   
10 #include <stack>   
11 #include <list>   
12 #include <vector>   
13 #include <cstdio>   
14 #include <cstdlib>   
15 #include <cstring>   
16 #include <cmath>   
17 #include <ctime>   
18 #include <ctype.h> 
19 using namespace std;
20 
21 #define MAXN 500+10
22 
23 int graph[MAXN][MAXN];
24 int path[MAXN];
25 bool vst[MAXN];
26 int c[MAXN][2],d[MAXN][2];            //构建正确的模型很重要
27 int cnt1,cnt2;
28 int n,m,p;
29 
30 int dfs(int v)
31 {
32     for(int i=1;i<cnt2;i++)
33         if(!vst[i]&&graph[v][i])
34         {
35             vst[i]=1;
36             if(path[i]==-1||dfs(path[i]))
37             {
38                 path[i]=v;
39                 return true;
40             }
41         }
42     return false;
43 }
44 
45 int hungary()
46 {
47     int cnt=0;
48     memset(path,-1,sizeof(path));
49     for(int i=1;i<cnt1;i++)
50     {
51         memset(vst,0,sizeof(vst));
52         if(dfs(i))
53             cnt++;
54     }
55     return cnt;
56 }
57 
58 int main()
59 {
60     char ch1,ch2;
61     int a,b;
62     int ans;
63     int i,j;
64     while(~scanf("%d%d%d",&n,&m,&p))
65     {
66         cnt1=cnt2=1;
67         memset(graph,0,sizeof(graph));
68         for(i=1;i<=p;i++)
69         {
70             getchar();
71             scanf("%c%d %c%d",&ch1,&a,&ch2,&b);
72             if(ch1=='C')
73             {
74                 c[cnt1][0]=a;
75                 c[cnt1++][1]=b;
76             }
77             else
78             {
79                 d[cnt2][0]=a;
80                 d[cnt2++][1]=b;
81             }
82         }
83         for(i=1;i<cnt1;i++)
84             for(j=1;j<cnt2;j++)
85             {
86                 if(c[i][0]==d[j][1]||c[i][1]==d[j][0])
87                     graph[i][j]=1;
88             }
89         ans=hungary();
90         printf("%d\n",p-ans);
91     }
92     return 0;
93 }
原文地址:https://www.cnblogs.com/XBWer/p/2637748.html