hdu2768-Cat vs. Dog:图论:二分匹配

Cat vs. Dog

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1602    Accepted Submission(s): 606

Problem Description

The
latest reality show has hit the TV: ``Cat vs. Dog‘‘. In this show, a
bunch of cats and dogs compete for the very prestigious Best Pet Ever
title. In each episode, the cats and dogs get to show themselves off,
after which the viewers vote on which pets should stay and which should
be forced to leave the show.

Each viewer gets to cast a vote on
two things: one pet which should be kept on the show, and one pet which
should be thrown out. Also, based on the universal fact that everyone is
either a cat lover (i.e. a dog hater) or a dog lover (i.e. a cat
hater), it has been decided that each vote must name exactly one cat and
exactly one dog.

Ingenious as they are, the producers have
decided to use an advancement procedure which guarantees that as many
viewers as possible will continue watching the show: the pets that get
to stay will be chosen so as to maximize the number of viewers who get
both their opinions satisfied. Write a program to calculate this maximum
number of viewers.

Input

On the first line one positive number: the number of testcases, at most 100. After that per testcase:

* One line with three integers c, d, v (1 ≤ c, d ≤ 100 and 0 ≤ v ≤ 500): the number of cats, dogs, and voters.
* v lines with two pet identifiers each. The first is the pet that
this voter wants to keep, the second is the pet that this voter wants to
throw out. A pet identifier starts with one of the characters `C‘ or
`D‘, indicating whether the pet is a cat or dog, respectively. The
remaining part of the identifier is an integer giving the number of the
pet (between 1 and c for cats, and between 1 and d for dogs). So for
instance, ``D42‘‘ indicates dog number 42.

Output

Per testcase:

* One line with the maximum possible number of satisfied voters for the show.

Sample Input

2
1 1 2
C1 D1
D1 C1
1 2 4
C1 D1
C1 D1
C1 D2
D2 C1

Sample Output

1
3

Source

NWERC 2008


算法:将喜欢猫和喜欢狗的人分开,就形成了一个二分图,这样喜欢猫(狗)的人一定不会冲突的,然后扫描一次,将互相矛盾的人连一条边。

二分图的最大独立集就是答案。由已知定理有:二分图最大独立集=顶点数-二分图最大匹配。求二分图最大匹配即可。

 1 const int MAXN = 510;
 2 int uN,vN;//u,v的数目,使用前面必须赋值
 3 int g[MAXN][MAXN];//邻接矩阵
 4 int linker[MAXN];
 5 bool used[MAXN];
 6 #include <memory.h>
 7 bool dfs(int u)
 8 {
 9     for(int v = 0; v < vN; v++)
10         if(g[u][v] && !used[v])
11         {
12             used[v] = true;
13             if(linker[v] == -1 || dfs(linker[v]))
14             {
15                 linker[v] = u;
16                 return true;
17             }
18         }
19     return false;
20 }
21 int hungary()
22 {
23     int res = 0;
24     memset(linker,-1,sizeof(linker));
25     for(int u = 0; u < uN; u++)
26     {
27         memset(used,false,sizeof(used));
28         if(dfs(u))res++;
29     }
30     return res;
31 }
32
33 #include <iostream>
34 #include <stdio.h>
35 #include <string.h>
36 using namespace std;
37
38
39 int getint(char s[])
40 {
41     int ans=0;
42     for(int i=0; i<strlen(s); i++)
43     {
44         ans=ans*10+s[i]-‘0‘;
45     }
46     return ans;
47 }
48
49 typedef pair<int,int> CPair;
50
51 CPair upair[510],vpair[510];
52 int main()
53 {
54     #ifndef ONLINE_JUDGE
55     freopen("in.txt","r",stdin);
56     #endif // ONLINE_JUDGE
57     int T;
58     cin>>T;
59     while(T--)
60     {
61         memset(g,0,sizeof g);
62         int nc,nd,n;
63         uN=vN=0;
64         scanf("%d%d%d",&nc,&nd,&n);
65         for(int i=0; i<n; i++) // 人的数量
66         {
67             char s1[20],s2[20];
68             scanf("%s%s",s1,s2); // C1 D1
69             int ci=getint(s1+1),di=getint(s2+1);
70             if(s1[0]==‘C‘)
71             {
72                 // 放到第一个集合
73                 upair[uN++]=CPair(ci,di);
74             }
75             else
76             {
77                 vpair[vN++]=CPair(ci,di);
78             }
79         }
80         // 构图
81         for(int i=0;i<uN;i++)
82             for(int j=0;j<vN;j++)
83             {
84                 // 矛盾的话就连一条边
85                 if(upair[i].first==vpair[j].second || upair[i].second==vpair[j].first)
86                     g[i][j]=1;
87             }
88
89         int ans=uN+vN-hungary();
90         printf("%d\n",ans);
91     }
92     return 0;
93 }
时间: 2024-11-03 21:54:56

hdu2768-Cat vs. Dog:图论:二分匹配的相关文章

HDU 3289 Cat VS Dog (二分匹配 求 最大独立集)

题意:每个人有喜欢的猫和不喜欢的狗.留下他喜欢的猫他就高心,否则不高心.问最后最多有几个人高心. 思路:二分图求最大匹配 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdlib> 6 #include<string> 7 #include<cmath> 8 #include<

UVA 12168 - Cat vs. Dog(二分图匹配+最大独立集)

UVA 12168 - Cat vs. Dog 题目链接 题意:给定一些猫爱好者,和一些狗爱好者,每个人都有一个喜欢的猫(狗),和一个讨厌的狗(猫),要问现在给一种方案,使得尽量多的人被满足 思路:二分图匹配最大独立集,猫爱好者和狗爱好者矛盾的建边,做一次最大独立集即可 代码: #include <cstdio> #include <cstring> #include <vector> using namespace std; const int N = 505; in

hdu 2768 Cat vs. Dog (二分匹配)

Cat vs. Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1422    Accepted Submission(s): 534 Problem Description The latest reality show has hit the TV: ``Cat vs. Dog''. In this show, a bunch

hdu 3829 Cat VS Dog 二分图匹配 最大点独立集

Cat VS Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) 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

动手动脑(课堂作业05)第二句错误显示为:类型不匹配:不能从 Mammal 转换为 Dog 第三句错误显示为:类型不匹配:不能从 Cat 转换为 Dog

---恢复内容开始--- 为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来? 构造函数(constructor)是一种特殊的方法 .主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 .特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载.构造函数的功能主要用于在类的对象创建时定义初始化的状态.构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量.子类

kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树

二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图. 1.一个二分图中的最大匹配数等于这个图中的最小点覆盖数 König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数.如果你还不知道什么是最小点覆盖,我也在这里说一下:假如选

二分匹配

PS:二分图匹配这一章的内容,我认为最重要的是要弄清楚概念. 一些定义: 二分图:二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如 果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联 的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个 二分图.记为G=(A,B;E). 二分图匹配:给定一个二分图G,M为G边集的一个子集,如果M满足当中的任意两条边都不依附于同一个顶点,则称M是一个匹配. 需要强调的是:

最大权二分匹配

图论里有一个非常经典的算法,那就是二分匹配,只是仅仅是简单的匹配有时并不能解决我们的问题,比方匹配带权的情况.引申的一个非常重要的问题就是分配问题,比方给n个人分派m个任务,每一个人都有不同的成本,怎样分配能使得成本最小就是这种问题,这种问题我们统称为二分图的最大权匹配问题. 解决这类问题的最好的方法应该就是KM 算法.详细细节能够自己百度! 以下是我的代码,我主要还是用了类来写,认为这样比較好理解! #include<iostream> #include<cstdio> #inc

HDU——2768 Cat vs. Dog

Cat vs. Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2279    Accepted Submission(s): 886 Problem Description The latest reality show has hit the TV: ``Cat vs. Dog''. In this show, a bunc