KM算法模板题。
友情链接:百度百科KM算法:http://bk.baidu.com/view/739278.htm
注意事项:
1、在每次Dfs做匈牙利算法的时候都要将可更新值slack赋为无穷大
2、在扩大相等子图的时候注意要将不在交错树中的y节点的slack值减去更新值d
3、百度百科上给的程序复杂度为O(n^4),我的代码时间复杂度是O(n^3)
代码:
Program KM;//By_Thispoet
Const
maxn=200;
Var
i,j,k,m,n,toth,totm,d,ans :Longint;
slack,res,a,b :Array[1..maxn]of Longint;
vx,vy :Array[1..maxn]of Boolean;
pre,other,last,data :Array[1..maxn*200]of Longint;
ch :Char;
xh,yh,xm,ym :Array[1..maxn]of Longint;
ok :Boolean;
Function Min(i,j:Longint):Longint;
begin
if i<j then exit(i);exit(j);
end;
Function Dfs(i:Longint):Boolean;
var j,k:Longint;
begin
j:=last[i];
vx[i]:=true;
while j<>0 do
begin
k:=other[j];
if (not vy[k])and(data[j]=a[i]+b[k])then
begin
vy[k]:=true;
if (res[k]=0)or(Dfs(res[k])) then
begin
res[k]:=i;
exit(true);
end;
end else if (not vy[k])and(data[j]<a[i]+b[k]) then
slack[k]:=Min(slack[k],a[i]+b[k]-data[j]);
j:=pre[j];
end;
exit(false);
end;
BEGIN
readln(n,m);
while not((n=0)and(m=0)) do
begin
toth:=0;totm:=0;
for i:=1 to n do
begin
for j:=1 to m do
begin
read(ch);
if ch='m' then
begin
inc(totm);
xm[totm]:=i;ym[totm]:=j;
end else if ch='H' then
begin
inc(toth);
xh[toth]:=i;yh[toth]:=j;
end;
end;
readln;
end;
//init
fillchar(last,sizeof(last),0);
fillchar(b,sizeof(b),0);
fillchar(a,sizeof(a),0);
k:=0;
for i:=1 to totm do
begin
for j:=1 to toth do
begin
inc(k);pre[k]:=last[i];last[i]:=k;other[k]:=j;
data[k]:=300-(abs(xm[i]-xh[j])+abs(ym[i]-yh[j]));//need to be changed
if data[k]>a[i] then a[i]:=data[k];
end;
end;
//Build_Graph
n:=totm;
fillchar(res,sizeof(res),0);
for j:=1 to n do
begin
repeat
ok:=false;
fillchar(vx,sizeof(vx),0);
fillchar(vy,sizeof(vy),0);
fillchar(slack,sizeof(slack),127);
if Dfs(j) then ok:=true;
if not ok then
begin
d:=maxlongint;
for i:=1 to n do if not vy[i] then d:=Min(d,slack[i]);
for i:=1 to n do
begin
if vx[i] then dec(a[i],d);
if vy[i] then inc(b[i],d) else dec(slack[i],d);
end;
end;
until ok;
end;
//KM
ans:=0;
for i:=1 to n do inc(ans,a[i]);
for i:=1 to n do inc(ans,b[i]);
ans:=300*n-ans;
writeln(ans);
//Getans
readln(n,m);
//prepare for the next test case
end;
END.