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.

 

posted @ 2015-11-02 15:37  OI_songer  阅读(231)  评论(0编辑  收藏  举报