昨天组队赛做题,其中有一个题用到了匈牙利算法,突然想起了这道题。
这道题比昨天做的那道题题目描述更加清晰,匈牙利算法的实质就是二分图的最大匹配。
例题——磕cp
Description
Alice喜欢嗑cp,她总是幻想她喜欢的男明星可以和她喜欢的女明星处cp, 已知n个男,m个女(男明星编号从1到n,女明星编号1到m),k组有可能发展成cp关系的组合, 一个人最多只能和一名异性处cp,Alice想知道她最多能嗑几组cp?
Input
第一行输入三个整数n,m,k(1<=n,m<=500,1<=k<=5e4),分别表示男明星个数,女明星个数,和有可能发展成cp的组合。接下来输入k行,每行两个整数u,v(1<=u<=n,1<=v<=m)表示编号为编号为u的男与编号为v的女可能成为cp。
Output
输出一个整数,表示Alice最多能嗑几组cp。
Sample
Input
2 3 4
1 1
1 3
2 1
2 2
Output
2
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define max 510
int line[max][max];//存储可以成为cp的人
int memory[max];//
int girl[max];//记录和女孩磕成cp的男孩
int n,m,k,x,y;
bool f(int x)
{
int i;
for(i=0; i<m; i++)
{
if(line[x][i]&&!memory[i])//如果两者可以磕cp并且该男孩和该女孩以前没有尝试过组cp
{
memory[i]=1;//已经尝试,下面代码为尝试的过程
if(girl[i]==-1||f(girl[i]))//如果该女孩目前没有男孩或者和该女孩组cp的男孩可以腾位置
{
gril[i]=x;//匹配成功
return true;
}
}
}
return false;
}
int g()
{
int i,sum=0;
for(i=0; i<n; i++)//遍历
{
memset(memory,0,sizeof(memory));
if(f(i))sum++;
}
return sum;
}
int main()
{
scanf("%d %d %d",&n,&m,&k);
memset(girl,-1,sizeof(girl));//如果编号从零开始,这里初始化不要初始化为0
memset(line,0,sizeof(line));
while(k--)
{
scanf("%d %d",&x,&y);
line[x][y]=1;
}
printf("%d\n",g());
return 0;
}
哎,做个题都是cp,天天打代码的我们学校什么时候给分配对象啊!!!