设有M个工人x1,x2, …, xm,和N项工作y1,y2, …, yn,规定每个工人至多做一项工作,而每项工作至多分配一名工人去做。由于种种原因,每个工人只能胜任其中的一项或几项工作。问应怎样分配才能使尽可能多的工人分配到他胜任的工作。这个问题称为人员分配问题。
人员分配问题可以用图的语言来表述。令X={x1, x2, …, xm},Y={y1, y2, …,yn},构造二分图G=(X, Y, E)如下:
对于1≤i≤m,1≤j≤n,当且仅当工人xi胜任工作yi时,G中有一条边xiyi,于是人员分配问题就成为在G中求一个最大匹配的问题。
标程:
type
node=record
x,y,next:longint;
end;
const
maxn=100;
maxv=3000;
var
g:array [1..maxv] of node;
ls,link:array [1..maxn] of longint;
cover:array [1..maxn] of boolean;
n,e,m:longint;
procedure init;
vari,x,y:longint;
begin
readln(m,n);
readln(e);
fori:=1 to e do
begin
with g[i] do
begin
readln(x,y);
next:=ls[x];
ls[x]:=i;
end;
end;
end;
function find(p:longint):boolean;
var
t,q:longint;
begin
find:=true;
t:=ls[p];
while t>0 do
with g[t] do
begin
if cover[y]=false then
begin
cover[y]:=true;
q:=link[y];
link[y]:=p;
if (q=0) or find(q) then exit;
link[y]:=q;
end;
t:=next;
end;
find:=false;
end;
procedure main;
vari:longint;
begin
fori:=1 to n do
begin
fillchar(cover,sizeof(cover),0);
find(i);
end;
end;
procedure print;
var
i,s:longint;
begin
s:=0;
fori:=1 to n do
iflink[i]<>0 then s:&#61;s&#43;1;
writeln(s);
{ for i:&#61;1 to n do
iflink[i]<>0 then writeln(link[i],&#39; &#39;,i);}
end;
begin
init;
main;
print;
end.