jzoj P1751 Span___枚举+最小生成树

题目大意:

 某国有N个村子,M条道路,为了实现“村村通工程”现在要”油漆”N-1条道路(因为某些人总是说该国所有的项目全是从国外进口来的,只是漆上本国的油漆罢了),因为“和谐”是此国最大的目标和追求,以致于对于最小造价什么的都不在乎了,只希望你所选出来的最长边与最短边的差越小越好。
 
数据组数Tot<=6
 1:2 ≤ n ≤ 100 and 0 ≤ m ≤ n(n − 1)/2
 2:每条边的权值小于等于10000
 3:保证没有自环,没有重边

题解:

这题数据太小了,
可行的方法是直接排序边权,
然后枚举一个起点,做最小生成树,然后并查集优化即可
时间复杂度:O(Tn^2 log n)

代码:

var
     s,t,w:Array [0..50001] of longint;
     f,list:array [0..101] of longint;
     ans,num,op,i,j,p,n,m,x1,y1:longint;

procedure qsort(l,r:longint);
var
     i,j,mid:longint;
begin
     if l>=r then exit;
     i:=l; j:=r;
     mid:=w[(l+r) div 2];
     repeat
           while (w[i]do inc(i);
           while (w[j]>mid) do dec(j);
           if i<=j then
              begin
                   s[0]:=s[i];s[i]:=s[j];s[j]:=s[0];
                   t[0]:=t[i];t[i]:=t[j];t[j]:=t[0];
                   w[0]:=w[i];w[i]:=w[j];w[j]:=w[0];
                   inc(i); dec(j);
              end;
     until i>j;
     qsort(i,r);
     qsort(l,j);
end;

function find(x:longint):longint;
begin
     if f[x]=x then exit(x);
     f[x]:=find(f[x]);
     exit(f[x]);
end;

begin
     readln(op);
     while op>=1 do
        begin
             readln(n,m);
             for i:=1 to m do readln(s[i],t[i],w[i]);
             qsort(1,m);
             ans:=maxlongint;
             for i:=1 to n do f[i]:=i;
             for i:=1 to m do
                begin
                     for j:=1 to n do f[j]:=j;
                     num:=0;
                     for j:=i to m do
                         begin
                               x1:=find(s[j]);
                               y1:=find(t[j]);
                               if find(x1)<>find(y1) then
                               begin
                                      f[x1]:=y1;
                                      inc(num);
                               end;
                               if num=n-1 then break;
                         end;
                     if num=n-1 then
                        if w[j]-w[i]then ans:=w[j]-w[i];
                end;
             if ans=maxlongint then writeln('-1')
                               else writeln(ans);
             dec(op);
        end;
end.

你可能感兴趣的:(jzoj P1751 Span___枚举+最小生成树)