kruskal算法-Pascal
马上就快要考试了,然而突然发现自己图论已经废了,于是再都打一遍练练手。。。。。。
1 const 2 maxn=100; 3 maxe=maxn*maxn; 4 5 type 6 edge=record //edge记录每一条边,a,b为它所连接的两个点,len为边长 7 a,b:longint; 8 len:longint; 9 end; 10 11 var 12 edges:array[0..maxe]of edge; 13 p,r:array[0..maxn]of longint; 14 n,e:longint; 15 16 procedure swap(a,b:integer); 17 begin 18 edges[0]:=edges[a]; 19 edges[a]:=edges[b]; 20 edges[b]:=edges[0]; 21 end; 22 23 procedure qsort(l,r:integer); //快排 24 var 25 i,j,mid,t:integer; 26 begin 27 mid:=edges[random(r-l+1)+l].len; 28 i:=l; j:=r; 29 repeat 30 while edges[i]<mid do inc(i); 31 while edges[j]>mid do dec(j); 32 if i<=j then 33 begin 34 swap(i,j); 35 inc(i); 36 dec(j); 37 end; 38 until i>j; 39 if l<j then qsort(l,j); 40 if r>i then qsort(i,r); 41 end; 42 43 procedure init; //输入 44 var 45 i:integer; 46 begin 47 assign(input,'g.in'); 48 reset(input); 49 readln(n,e); 50 for i:=1 to e do 51 readln(edges[i].a,edges[i].b,edges[i].len); 52 for i:=1 to n do 53 p[i]:=i; 54 randomize; 55 end; 56 57 function find(x:integer):integer; //并查集:查找x的祖先 58 begin 59 if x<>p[x] then p[x]:=find(p[x]); 60 exit(p[x]); 61 end; 62 63 procedure union(a,b:longint); //并查集:合并a,b所在的集合 64 var 65 t:integer; 66 begin 67 a:=find(a); 68 b:=find(b); 69 if r[a]>r[b] then 70 begin 71 t:=a; 72 a:=b; 73 b:=t; 74 end; 75 if r[a]=r[b] then inc(r[a]); 76 p[a]:=b; 77 end; 78 79 procedure kruskal; //kruskal算法 80 var 81 en:longint; //记录当前为第几条边 82 count:longint; //记录当前加入了几条边 83 tot:longint; //记录当前已加入边的边权和 84 begin 85 count:=0; 86 en:=0; 87 tot:=0; //初始化 88 while count<n-1 do //当已加入的边数小于(n-1)个时 89 begin 90 inc(en); 91 with edges[en]do 92 begin 93 if find(a)<>find(b) then //如果a,b不在同一集合内 94 begin 95 union(a,b); //合并a,b 96 writeln(a,'--',b,':',len); 97 inc(tot,len); 98 inc(count); 99 end; 100 end; 101 end; 102 end; 103 104 begin //main 105 init; 106 qsort(1,e); //根据边长大小进行快排 107 kruskal; 108 end.