【NOIP2017练习】论战大原题(并查集)

题意:给定一个n个点m条边的无向图。定义一条路径的长度为路径上最小边的权值。

定义dist(i,j)为起点为i,终点为j的长度最长的路径的长度。求出第k大的dist(i,j)(i<j)。

对于所有的数据,保证n≤100000,m≤min(n^2,200000),k≤n(n-1)/2且图连通,w≤10^9。

思路:lyy去年出的题

 1 var a,b,c,fa:array[1..300000]of longint;
 2     size:array[1..300000]of int64;
 3     n,m,i,u,v:longint;
 4     k:int64;
 5 
 6 procedure swap(var x,y:longint);
 7 var t:longint;
 8 begin
 9  t:=x; x:=y; y:=t;
10 end;
11 
12 procedure qsort(l,r:longint);
13 var i,j,mid:longint;
14 begin
15  i:=l; j:=r; mid:=c[(l+r)>>1];
16  repeat
17   while mid<c[i] do inc(i);
18   while mid>c[j] do dec(j);
19   if i<=j then
20   begin
21    swap(a[i],a[j]);
22    swap(b[i],b[j]);
23    swap(c[i],c[j]);
24    inc(i); dec(j);
25   end;
26  until i>j;
27  if l<j then qsort(l,j);
28  if i<r then qsort(i,r);
29 end;
30 
31 function find(k:longint):longint;
32 begin
33  if k<>fa[k] then fa[k]:=find(fa[k]);
34  exit(fa[k]);
35 end;
36 
37 begin
38  assign(input,'original.in'); reset(input);
39  assign(output,'original.out'); rewrite(output);
40  readln(n,m,k);
41  for i:=1 to m do readln(a[i],b[i],c[i]);
42  for i:=1 to n do
43  begin
44   size[i]:=1; fa[i]:=i;
45  end;
46  qsort(1,m);
47  for i:=1 to m do
48  begin
49   u:=find(a[i]); v:=find(b[i]);
50   if u<>v then
51   begin
52    k:=k-size[u]*size[v];
53    fa[v]:=u; size[u]:=size[u]+size[v];
54   end;
55   if k<=0 then
56   begin
57    writeln(c[i]);
58    break;
59   end;
60  end;
61 
62 
63  close(input);
64  close(output);
65 end.
原文地址:https://www.cnblogs.com/myx12345/p/7652786.html