题意:判断最小生成树是否唯一.
分析:先求出一棵最小生成树,记下最小权值为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.