Понятная программа решения с быстрым пересчетом
const max=100;{размер большего из двух множеств}
var new: array[0..max] of boolean;
res, min, u, v: array[0..max] of integer;
n, i, j, /state>/state>>/>/state>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>/place>/place>>/>/place>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>del/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>: integer;
f: boolean;
function a(i,j:integer):integer;
begin
a:=c[j,i];{транспонированная матрица исходных данных}
end;
function dfs(i: integer): boolean;
{пытается найти вершине j пару}
var j: integer;
begin
if new[i] then {j в текущем паросочетании уже просмотрена}
begin dfs:= false; exit end;
new[i]:= true;
for j:= 1 to n do
if a(i, j)-u[i]-v[j]=0 then
if (res[j] = 0) or dfs(res[j]) then
begin
dfs:=true; res[j]:=i; exit
end
else
else
if ((res[j] = 0) or (not new[res[j]])) and
(a(i, j)-u[i]-v[j] < min[j]) then begin
min[j]:=a(i, j)-u[i]-v[j];
if /state>/state>>/>/state>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>/place>/place>>/>/place>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>del/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>min[j] then /state>/state>>/>/state>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>/place>/place>>/>/place>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>del/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>:=min[j];
end;
dfs:=false;
end;
begin {/place>/place>>/>/place>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>Main/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>}
fillchar(res,sizeof(res),0);
fillchar(u,sizeof(v),0);
fillchar(v,sizeof(v),0);
n :=100;
for i:= 1 to n do begin
{каждой вершине одного из множеств находим назначение}
for j:=1 to n do min[j]:=maxint;
repeat
/state>/state>>/>/state>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>/place>/place>>/>/place>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>del/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>:=maxint;
fillchar(new,sizeof(new),false);
f := dfs(i);{в эффективной программе заменяется на перестройку цепочки}
if not f then begin
for j:=1 to n do
if (res[j]>0)and new[res[j]] then begin
v[j]:=v[j]-del;
u[res[j]]:=u[res[j]]+del
end;
u[i]:=u[i]+/state>/state>>/>/state>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>/place>/place>>/>/place>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>del/place>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>/state>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>>/>;{в этой строке результата нет, но она помечена!!!}
end;
until f;
end;
for j:= 1 to n do
writeln(j,' ',res[j])
end.