【最大匹配】人员分配

人员分配

题目

设有M个工人x1, x2, …, xm,和N项工作y1, y2, …, yn,规定每个工人至多做一项工作,而每项工作至多分配一名工人去做。由于种种原因,每个工人只能胜任其中的一项或几项工作。问应怎样分配才能使尽可能多的工人分配到他胜任的工作。这个问题称为人员分配问题。

输入

第一行两个整数m,n分别为工人数和工作数。
接下来一个整数s,为二分图的边数。
接下来s行,每行两个数ai,bi表示第ai个工人能胜任第bi份工作

输出

一个整数,表示最多能让多少个工人派到自己的胜任的工作上。

输入样例

3 3
4
1 2
2 1
3 3
1 3

输出样例

3

数据范围

1 < = m , n < = 100 1<=m,n<=100 1<=m,n<=100
1 < = s < = 10000 1<=s<=10000 1<=s<=10000

解题思路

就是求最大匹配常用匈牙利算法,就是从当前匹配(初始点为0)出发,检查每一个未标记点,然后从它出发寻找增广路,找到可增广路,就沿着这条增广路进行补充,知道不存在增广路为止

程序如下

#include
#include
#include
#include
using namespace std;
int m,n,k,ss,head[100001],v[100001],a,b,s[100001],l[100001],ans;
struct node
{
	int to,next;
}f[100001];
int find(int t)//查找最大匹配
{
	for (int i = head[t]; i; i = f[i].next)
	{
		int j = f[i].to;
		if (!s[j])
		{
		    int q = l[j];
		    l[j] = t;
		    s[j] = 1;
		    if (!q || find(q)) return 1;
		    l[j] = q;
		}
		
	}
	return 0;
}
int main()
{
	scanf("%d%d",&m,&n);
	scanf("%d",&ss);
	for(int i = 1;i <= ss; ++i)
	{
		scanf("%d%d",&a,&b);
		f[++k].next = head[a];//建二分图
		f[k].to = b;
		head[a] = k;
	}
	for(int i = 1;i <= m; ++i)
	{
		memset(s,0,sizeof(s));
		ans += find(i);
	}
	printf("%d",ans);
	return 0;
}

你可能感兴趣的:(最大匹配)