Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
不用求次小生成树,直接用kruscal的简单变形,0ms下面给大家介绍用Kruscal的简单变形就可以解决本题,时间复杂度为O(M+MlogM),包括了快排的时间复杂度,0MS。 注意到Kruscal贪心每次找出边权最小的边判断能否合并,假设找到了一条边权最小的边,其两个顶点所在集合的根节点分别为x和y, 向后搜寻边权与当前边相同的边(即当前边权最小的边不唯一),若搜寻到的边两个顶点的根节点同样是x和y,则这两个集合合并就有了两种方法, 此时就可以直接输出NotUnique!并退出。这样除了qsort以外的时间复杂度就被控制在O(m)以内。 type rec=record u,v,w:longint; end; var a:array[0..10000]of rec; fa:array[0..100]of longint; b:array[0..10000]of boolean; t,n,m,i,j,x,y,ans:longint; bool:boolean; procedure qsort(l,r:longint); var i,j,x:longint; y:rec; begin i:=l; j:=r; x:=a[(l+r)>>1].w; repeat while a[i].w<x do inc(i); while x<a[j].w do dec(j); if not(i>j) then begin y:=a[i]; a[i]:=a[j]; a[j]:=y; inc(i); dec(j); end; until i>j; if l<j then qsort(l,j); if i<r then qsort(i,r); end; function find(x:longint):longint; begin if x=fa[x] then exit(x); fa[x]:=find(fa[x]); exit(fa[x]); end; begin readln(t); repeat dec(t); readln(n,m); for i:=1 to m do with a[i] do read(u,v,w); qsort(1,m); fillchar(b,sizeof(b),0); for i:=1 to n do fa[i]:=i; bool:=false; ans:=0; i:=0; while i<m do begin inc(i); if b[i] then continue; x:=find(a[i].u); y:=find(a[i].v); if x=y then continue; for j:=i+1 to m do with a[j] do if not b[j] and(w=a[i].w)and(((find(u)=x)and(find(v)=y))or((find(u)=y)and(find(v)=x))) then begin bool:=true; b[j]:=true; end else break; if bool then break; fa[y]:=x; inc(ans,a[i].w); end; if bool then writeln('Not Unique!') else writeln(ans); until t=0; end. Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator