最大匹配 人員分配

2021-07-13 14:47:58 字數 1681 閱讀 3833

題目大意

設有m個工人x1,x2, …, xm,和n項工作y1, y2, …, yn,規定每個工人至多做一項工作,而每項工作至多分配一名工人去做。由於種種原因,每個工人只能勝任其中的一項或幾項工作。問應怎樣分配才能使盡可能多的工人分配到他勝任的工作。分析

對於1≤i≤m,1≤j≤n,當且僅當工人xi勝任工作yi時,g中有一條邊xiyi,於是人員分配問題就成為在g中求乙個最大匹配的問題。

求最大匹配常用匈牙利演算法,它的基本思想是:對於已知的匹配m,從x中的任一選定的m非飽和點出發,用標號法尋找m增廣鏈。如果找到m增廣鏈,則m就可以得到增廣;否則從x中另乙個m非飽和點出發,繼續尋找m增廣鏈。重複這個過程直到g中不存在增廣鏈結束,此時的匹配就是g的最大匹配。**

type

arr=record

x,y,w:longint;

next:longint;

end;

var a:array[1..10000] of arr;

v:array[1..30000] of boolean;

st,ls:array[1..30000] of longint;

i,j,k:longint;

n,m,nm:longint;

function find(r:longint):boolean;

var i,j,k:longint;

begin

find:=true;

i:=ls[r];

while i<>0 do

begin

with a[i] do

if not v[y]

then

begin

k:=st[y]; st[y]:=r; v[y]:=true;

if (k=0) or find(k) then exit;

st[y]:=k;

end;

i:=a[i].next;

end;

find:=false;

end;

procedure main;

var i,j,k:longint;

z:boolean;

begin

for i:=1 to n do

begin

fillchar(v,sizeof(v),0);

z:=find(i);

end;

end;

begin

readln(n,m);

readln(nm);

for i:=1 to nm do

begin

with a[i*2-1] do

begin

readln(x,y);

y:=y+n;

next:=ls[x];

ls[x]:=i*2-1;

end;

with a[i*2] do

begin

x:=a[i*2-1].y;

y:=a[i*2-1].x;

next:=ls[x];

ls[x]:=i*2;

end;

end;

main;

j:=0;

for i:=n to n+m do

if st[i]<>0 then j:=j+1;

write(j);

end.

匈牙利 最大匹配 人員分配

description 設有m個工人x1,x2,xm,和n項工作y1,y2,yn,規定每個工人至多做一項工作,而每項工作至多分配一名工人去做。由於種種原因,每個工人只能勝任其中的一項或幾項工作。問應怎樣分配才能使盡可能多的工人分配到他勝任的工作。這個問題稱為人員分配問題。input 第一行兩個整數m...

SSL 1338 最大匹配 人員分配

題意 description 設有m個工人x1,x2,xm,和n項工作y1,y2,yn,規定每個工人至多做一項工作,而每項工作至多分配一名工人去做。由於種種原因,每個工人只能勝任其中的一項或幾項工作。問應怎樣分配才能使盡可能多的工人分配到他勝任的工作。這個問題稱為人員分配問題。讀入 input 第一...

最大匹配 人員分配 鄰接矩陣

description 設有m個工人x1,x2,xm,和n項工作y1,y2,yn,規定每個工人至多做一項工作,而每項工作至多分配一名工人去做。由於種種原因,每個工人只能勝任其中的一項或幾項工作。問應怎樣分配才能使盡可能多的工人分配到他勝任的工作。這個問題稱為人員分配問題。input 第一行兩個整數m...