最小生成树(kruskal)

Kruskal算法是一种用来寻找最小生成树的算法,由Joseph Kruskal在1956年发表。用来解决同样问题的还有Prim算法和Boruvka算法等。三种算法都是贪婪算法的应用。和Boruvka算法不同的地方是,Kruskal算法在图中存在相同权值的边时也有效。

 

时间复杂度:elog2e  e为图中的边数

 

原理可以参考这篇文章:

http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html

 

实现如下:

 1 #include <iostream>
 2 #include <vector>
 3 #include <queue>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 vector<pair<int,int> > eg[100];
 8 
 9 typedef pair<int,int> pa;
10 
11 struct node
12 {
13           int x,y,w;
14 
15           node(int a,int b,int c)
16           { x=a;y=b;w=c;}
17 
18           bool operator <(const node &a)const
19           { return w<a.w;}
20           //为了实现sort,<是升序(小的在前),>是降序
21 };
22 
23 void kruskal(int n,int d)
24 {
25           int vset[100];
26           //辅助数组,判定两个顶点是否连通
27 
28           vector<node> E;
29           //保存所有边
30           
31           int k,j;
32           
33           //init
34           for(int i = 0;i<n;i++)
35           {
36                     vset[i] = i;
37                     for(int j = 0;j<eg[i].size();j++)
38                     {
39                               pa x = eg[i][j];
40                               E.push_back(node(i,x.first,x.second));
41                     }
42           }
43           sort(E.begin(),E.end());
44 
45           k = 1;
46           //生成的边数,最后要刚好为总边数
47           int m = 0,sn1,sn2;
48           //E中的下标
49           
50           while(k<n)
51           {
52                     //sn1和sn2为两个集合
53                     sn1 = vset[E[m].x];
54                     sn2 = vset[E[m].y];
55                     if(sn1!=sn2)
56                     {
57                               cout<<E[m].x<<"->"<<E[m].y<<" : "<<E[m].w<<endl;
58                               //集合的表示
59                               for(int i = 0;i<n;i++)
60                                         if(vset[i] == sn2)
61                                                   vset[i] = sn1;
62                               k++;
63                     }
64                     m++;
65           }
66 
67 }
68 
69 
70 int main()
71 {
72           int n,d;
73           cin>>n>>d;
74           for(int i = 0;i<d;i++)
75           {
76                     int t,s,w;
77                     cin>>t>>s>>w;
78                     eg[t].push_back(make_pair(s,w));
79                     eg[s].push_back(make_pair(t,w));
80           }
81           kruskal(n,d);
82 
83 
84 
85 }
86 /*
87 6 8
88 0 1 2
89 0 3 4
90 1 4 4
91 2 0 5
92 2 5 2
93 3 4 3
94 3 5 7
95 5 4 3
96 */

 

posted @ 2015-11-26 13:59  qlky  阅读(285)  评论(0编辑  收藏  举报