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.