人員分配
題目
設有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
數據範圍
解題思路
就是求最大匹配常用匈牙利算法,就是從當前匹配(初始點爲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;
}