RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了。可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐。但是,每个女孩都有各自的想法,举个例子把,Rabbit只愿意和XHD或PQK做partner,Grass只愿意和linle或LL做partner,PrincessSnow愿意和水域浪子或伪酷儿做partner。考虑到经费问题,boss刘决定只让找到partner的人去坐过山车,其他的人,嘿嘿,就站在下面看着吧。聪明的Acmer,你可以帮忙算算最多有多少对组合可以坐上过山车吗?
Input
输入数据的第一行是三个整数K , M , N,分别表示可能的组合数目,女生的人数,男生的人数。0<K<=1000
1<=N 和M<=500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。
Output
对于每组数据,输出一个整数,表示可以坐上过山车的最多组合数。
Sample Input
6 3 3
1 1
1 2
1 3
2 1
2 3
Input
输入数据的第一行是三个整数K , M , N,分别表示可能的组合数目,女生的人数,男生的人数。0<K<=1000
1<=N 和M<=500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。
Output
对于每组数据,输出一个整数,表示可以坐上过山车的最多组合数。
Sample Input
6 3 3
1 1
1 2
1 3
2 1
2 3
3 1
Sample output
3
今天打算学习二分图匹配的一些知识,听队友说dfs的方法最容易理解效率也不错,早上看了一下确实如此。下面以此题为例讲解求解二分图最大匹配的算法。
以此题为例,第一个女生可以选择1,2,3,三个男生,第二个女生可以选择1,3两个男生,第3个女生可以选择第1个男生,使用贪心的思想,第一个女生先直接选择男生1,第二个女生再选择1,发现被选择了,这个时候有两种选择,第一不选择这个男生了,继续选择下一个男生,第二,让当前男生选择她,让之前的那个女生重新选择男生,这两者是有一个优先级的,如果直接不选择,可能这个女生接下来就没有能选择了,而前一个女生可能有多种选择,所以应该优先替换,如果替换失败,说明前一个女生也只有一个能选择,找不到新的男生了,这个时候当前女生就直接不选择了,因为反正只能选择一个,匹配数总是要少一个的。
分析之后,我们的算法就很显然了,依次处理女生,选择能选择的男生,如果该男生已经被选择过了,尝试替换,替换失败,没办法,考虑下一个男生。
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int max_node = 200;
vector<int> G[max_node];
int node_num,edge_num;
int girl[max_node],boy[max_node]; //girl[i]=j表示标号为i的女孩和标号为j的女孩配对,boy[i]相反
bool vis[max_node]; //标记男生的选择情况
void init(){
for(int i=0; i<max_node; i++){
G[i].clear();
}
}
int Find(int u){ //能否找到一个匹配
for(int i=0; i < G[u].size(); i++){
int x = G[u][i];
if(vis[x]) continue;
vis[x] = true;
if( !boy[x] || Find(boy[x])){ // 对于当前x,如果x还没有选择则可以直接选择,如果强行选择x,则x原来匹配的女生需要替换
girl[u] = x;
boy[x] = u;
return 1;
}
}
return 0;
}
int max_match(){
int ans = 0;
memset(boy, 0, sizeof(boy));
memset(girl, 0, sizeof(girl));
for(int i=1; i<=node_num; i++){
memset(vis, 0, sizeof(vis));
ans += Find(i);
}
}
int main(){
freopen("input.txt", "r", stdin);
while(scanf("%d%d" ,&node_num,&edge_num)!=EOF){
init();
int from, to;
for(int i=1; i<=edge_num; i++){
scanf("%d%d" ,&from, &to);
G[from].push_back(to);
}
printf("%d\n" ,max_match());
}
}