题意:判断最小生成树是否唯一.
分析:先求出一棵最小生成树,记下最小权值为W0.然后枚举树上的每条边,去掉以后再求一次最小生成树,
只要出现权值等于W0,那么最小生成树一定不唯一.
因为范围小,所以这样的算法可以过.还有更优的算法.
code:
type node=record u,v,w:longint; bo:boolean; end; const oo=100000000; var e:array[0..11000] of node; mst,f:array[0..110] of longint; min,d,datanum,n,m,o,now:longint; bool:boolean; procedure sort(l,r:longint); var i,j,mid:longint; temp:node; begin i:=l; j:=r; mid:=e[(l+r)>>1].w; repeat while e[i].w<mid do inc(i); while e[j].w>mid do dec(j); if i<=j then begin temp:=e[i]; e[i]:=e[j]; e[j]:=temp; inc(i); dec(j); end; until i>j; if i<r then sort(i,r); if j>l then sort(l,j); end; function getf(x:longint):longint; begin if f[x]<>x then f[x]:=getf(f[x]); exit(f[x]); end; procedure union(u,v:longint); begin f[u]:=v; end; function kruskal(v0:longint):longint; var i,mst_count,mstweight:longint; begin e[v0].bo:=true; for i:=1 to n do f[i]:=i; mst_count:=0; mstweight:=0; for i:=1 to m do begin if mst_count=n-1 then break; if (not e[i].bo)and(getf(e[i].u)<>getf(e[i].v)) then begin inc(mst_count); inc(mstweight,e[i].w); if v0=0 then mst[mst_count]:=i; union(getf(e[i].u),getf(e[i].v)); end; end; e[v0].bo:=false; if mst_count<n-1 then exit(-1) else exit(mstweight); end; begin readln(datanum); for d:=1 to datanum do begin readln(n,m); if m=0 then begin writeln(0); continue; end; for o:=1 to m do readln(e[o].u,e[o].v,e[o].w); min:=kruskal(0); for o:=1 to n-1 do begin now:=kruskal(mst[o]); if now=min then begin writeln('Not Unique!'); break; end; end; if now=min then continue else writeln(min); end; end.