POJ 2421[Constructing Roads]
不解释的MST,把已经有道路的两个村庄之间建一条长度为0的边,然后Kruskal。我开始是把已经有路的村庄合并,WA了
p.s.这个题的Discuss里面楼要倒了……
Var a,b,e,f:array[1..100000]of longint; n,m,sum,ans:longint; Procedure addgraph(x,y,z:longint); begin inc(m); a[m]:=x;b[m]:=y;e[m]:=z; end; Procedure init; var i,j,pre,k:longint; begin readln(n); fillchar(f,sizeof(f),0); for i:=1 to n do begin for j:=1 to n do begin read(pre); addgraph(i,j,pre); end; readln; end; readln(k); for i:=1 to k do begin read(j,pre); addgraph(j,pre,0); end; end; Procedure qsort(l,r:longint); var i,j,x,y:longint; begin i:=l;j:=r;x:=e[(l+r)shr 1]; Repeat while e[i]<x do inc(i); while e[j]>x do dec(j); if i<=j then begin y:=a[i];a[i]:=a[j];a[j]:=y; y:=b[i];b[i]:=b[j];b[j]:=y; y:=e[i];e[i]:=e[j];e[j]:=y; inc(i);dec(j); end; Until i>j; if i<r then qsort(i,r); if l<j then qsort(l,j); end; Function find(x:longint):longint; var k:longint; begin k:=x; while f[k]<>0 do k:=f[k]; find:=k; end; Procedure kruskal; var i,j,p,q:longint; begin qsort(1,m); for i:=1 to m do begin p:=find(a[i]); q:=find(b[i]); if p<>q then begin f[q]:=p; inc(sum,e[i]); inc(ans); end; if ans>=n-1 then break; end; writeln(sum); end; Begin init; kruskal; End.