您的位置:首页 > 其它

HDU 2063:过山车(匈牙利算法模板题)

2016-07-17 17:39 239 查看


过山车

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 17836    Accepted Submission(s): 7779


Problem Description

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
3 1
0

 

Sample Output

3

 

最小点覆盖数:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖所有的边

独立集:图中任意两个顶点都不相连的顶点集合

交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路。

增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路

定理1:二分图最大匹配==最小点覆盖数

定理2:顶点数-二分图最大匹配==最大独立集

定理3:最大匹配是增广路不存在的充要条件

匈牙利算法:

解决问题→二分图最大匹配,本质DFS,复杂度V*E

#include<stdio.h>
#include<string.h>
int k, n, m, road[505][505], vis[505], link[505];
int Sech(int x);
int main(void)
{
int i, a, b, ans;
while(scanf("%d", &k), k!=0)
{
ans = 0;
scanf("%d%d", &n, &m);
memset(road, 0, sizeof(road));
memset(link, 0, sizeof(link));
for(i=1;i<=k;i++)
{
scanf("%d%d", &a, &b); /*road[a][b]==1表示第a个男生对第b个女生有好感,否则没有*/
road[a][b] = 1;
}
for(i=1;i<=n;i++) /*算法思路:从第一个男生开始,尽可能让每个男生匹配成功,或是还有心仪的女生名花无主直接匹配,或是调整前面已有的匹配已达到找到自己心仪的女生*/
{
memset(vis, 0, sizeof(vis)); /*vis为标记数组,vis[k]==1表示第k个女生已经被查找过并试图改变过该妹子的归属问题,没有必要再次查找*/
if(Sech(i)==1) /*第i个男生匹配成功*/
ans++;
}
printf("%d\n", ans);
}
return 0;
}

int Sech(int x)
{
int i;
for(i=1;i<=m;i++) /*对于每个男生,先枚举每一个女生*/
{
if(vis[i]==0 && road[x][i]==1) /*如果这个女生还未被查找且这个男生对这个女生有好感*/
{
vis[i] = 1; /*标记*/
if(link[i]==0 || Sech(link[i])==1) /*如果这个女生名花无主或是可以腾出个位置*/
{ /*这其实是一个寻找增广路的过程*/
link[i] = x; /*恭喜这一对男女配对成功*/
return 1;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: