[Rq 333]发明测试数据

【题目】:发明测试数据

【来源】:Rq333

【关键字】:kurscal逆推

//================================================================================================

【分析】:根据生成树的步骤,先找最小边然后判断是否在一个集合中,再加入.所以先对所有边排序,则这条边的x,y所在集合的每两个点的连边(除此边)的值最小是该边权值加一。inc(ans,(num[x]*num[y]-1)*(e[t].d+1));

【小结】:反向思维

//================================================================================================

【代码】:

View Code
 1 type
2 rec = record
3 x, y: longint;
4 d: qword;
5 end;
6
7 var
8 n: longint;
9 ans: qword;
10 e: array[0..100010] of rec;
11 f, num: array[0..100010] of longint;
12 procedure qs(l, r: longint);
13 var
14 i, j, mid: longint;
15 t: rec;
16 begin
17 i := l;
18 j := r;
19 mid := e[(l+r) shr 1].d;
20 repeat
21 while e[i].d < mid do inc(i);
22 while e[j].d > mid do dec(j);
23 if i <= j then
24 begin
25 t := e[i];
26 e[i] := e[j];
27 e[j] := t;
28 inc(i);
29 dec(j);
30 end;
31 until i > j;
32 if l < j then qs(l,j);
33 if i < r then qs(i,r);
34 end;
35 procedure init;
36 var
37 i: longint;
38 begin
39 read(n);
40 for i := 1 to n-1 do read(e[i].x,e[i].y,e[i].d);
41 qs(1,n-1);
42 //for i := 1 to n-1 do writeln(e[i].x,' ',e[i].y,' ',e[i].d);
43 end;
44 function get(k: longint):longint;
45 begin
46 if f[k] = k then exit(k);
47 f[k] := get(f[k]);
48 get := f[k];
49 end;
50 procedure work;
51 var
52 i, x, y: longint;
53 begin
54 for i := 1 to n do f[i] := i;
55 for i := 1 to n do num[i] := 1;
56 for i := 1 to n-1 do
57 begin
58 x := get(e[i].x);
59 y := get(e[i].y);
60 ans := ans+(num[x]*num[y]-1)*(e[i].d+1)+e[i].d;
61 f[x] := y;
62 num[y] := num[x]+num[y];
63 //writeln(ans);
64 end;
65 end;
66 begin
67 init;
68 work;
69 writeln(ans);
70 //read(ans);
71 end.



你可能感兴趣的:(测试)