【最大匹配】人員分配

人員分配

題目

設有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<=1001<=m,n<=100
1<=s<=100001<=s<=10000

解題思路

就是求最大匹配常用匈牙利算法,就是從當前匹配(初始點爲0)出發,檢查每一個未標記點,然後從它出發尋找增廣路,找到可增廣路,就沿着這條增廣路進行補充,知道不存在增廣路爲止

程序如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章