USACO CONTEST 2002 OPEN 绿组.秘密管道[secret]

 



View Code
 1 program secret4;
2 var w,p,ans0:longint;
3 xx,yy,cost:array[0..20000] of longint;
4 use:array[0..20000] of boolean;
5 fa,tf,f:array[0..2000] of longint;
6
7 procedure QuickSort(l,r:longint);
8 var i,j,k,mid:longint;
9 begin
10 i:=l; j:=r; mid:=cost[(l+r) div 2];
11 repeat
12 while cost[i]<mid do inc(i);
13 while cost[j]>mid do dec(j);
14 if i<=j then
15 begin
16 k:=cost[i]; cost[i]:=cost[j]; cost[j]:=k;
17 k:=xx[i]; xx[i]:=xx[j]; xx[j]:=k;
18 k:=yy[i]; yy[i]:=yy[j]; yy[j]:=k;
19 inc(i); dec(j);
20 end;
21 until i>j;
22 if l<j then QuickSort(l,j);
23 if i<r then QuickSort(i,r);
24 end;
25
26 procedure init;
27 var i:longint;
28 begin
29 readln(w,p);
30 for i:=1 to p do read(xx[i],yy[i],cost[i]);
31 QuickSort(1,p);
32 end;
33
34 function find(x:longint):longint;
35 begin
36 if fa[x]=x then exit(x);
37 fa[x]:=find(fa[x]);
38 exit(fa[x]);
39 end;
40
41 procedure kruskal;
42 var i,j,fx,fy:longint;
43 begin
44 for i:=1 to w do fa[i]:=i;
45 i:=0; j:=0;
46 while (j<=w-1) and (i<=p) do
47 begin
48 inc(i);
49 if use[i] then
50 begin
51 fx:=find(xx[i]);
52 fy:=find(yy[i]);
53 if fx<>fy then
54 begin
55 inc(j);
56 fa[fx]:=fy;
57 ans0:=ans0+cost[i];
58 f[j]:=i;
59 end;
60 end;
61 end;
62 if (i=p) and (j<w-1) then ans0:=-1;
63 end;
64
65 procedure main;
66 var i,ans:longint;
67 begin
68 fillchar(use,sizeof(use),true);
69 ans0:=0;
70 kruskal;
71 ans:=maxlongint;
72 tf:=f;
73 for i:=1 to w-1 do
74 begin
75 use[tf[i]]:=false;
76 ans0:=0;
77 kruskal;
78 if (ans0>-1) and (ans0<ans) then ans:=ans0;
79 use[tf[i]]:=true;
80 end;
81 if ans=maxlongint then ans:=-1;
82 writeln(ans);
83 end;
84
85 Begin
86 assign(input,'secret.in'); reset(input);
87 assign(output,'secret.out'); rewrite(output);
88
89 init;
90 main;
91
92 close(input); close(output);
93 End.

这是kruskal的次小生成树。其实还可以优化的。 只不过懒得了。能过教师机就成了。

by the way

我之前的一遍是有用到 并查集来优化 kruskal 的

View Code
 1 procedure union(x,y:longint);
2 begin
3 if r[y]<r[x] then
4 begin
5 y:=y xor x;
6 x:=y xor x;
7 y:=y xor x;
8 end
9
10 function find(x:longint):longint;
11 begin
12 if x<>p[x] then p[x]:=find(p[x]);
13 exit(p[x]]);
14 end;
15
16 function clear:boolean;
17 var i,t:longint;
18 begin
19 clear:=true;
20 t:=find(1);
21 for i:=2 to m do
22 if find(i)<>t then exit(false);
23 end;
24
25 procedure solve;
26 var i,k:longint;
27 begin
28 for i:=1 to n do
29 begin
30 if clear then exit;
31 if find(a[i].f)<>find(a[i].t) then
32 begin
33 inc(ans,a[i].c);
34 union(find(a[i].f),find(a[i].t));
35 end;
36 end;
37 end;

=======

就是这样。