最小生成树(Minimum Spanning Tree)

使用贪心策略,伪代码如下

mst
1 GENERIC-MST(G,w)
2 A=空集
3 while(A不形成生成树)
4 找到一条安全边
5 将此边添加到A中去
6 return A

 在Kruskal算法中,集合A是一个森林,加入集合A中的安全边总是图中连接两个不同连通分支的最小权边。

在Prim算法中,集合A仅形成单棵树,添加入集合A的安全边总是连接树与一个不在树中得顶点的最小权边。

 

info
 1 typedef struct Edge
2 {
3 int adj_vertex;
4 int weight;
5 struct Edge* next;
6 }Edge;
7
8 typedef struct Vertex
9 {
10 int vertex;
11 Edge* head;
12 }Vertex;
13
14 //structure of edge
15 typedef struct Edge_MST
16 {
17 int u;
18 int v;
19 int weight;
20 }Edge_MST;
21
22 typedef struct Graph
23 {
24 Vertex vertices[50];
25 Edge_MST edges[50];
26 int vertex_num;
27 int edge_num;
28 }Graph;
29
30 void Create_Graph(Graph* g);
31 void Mst_Kruskal(const Graph* g);
32 void Mst_Prim(const Graph* g,int vertex);

 

View Code
 1 void Create_Graph(Graph* g)
2 {
3 cout <<"Enter the number of vertices:";
4 cin >>g->vertex_num;
5 cout <<endl<<"Enter the number of edges:";
6 cin >>g->edge_num;
7 for(int i=0;i<g->vertex_num;++i)
8 {
9 g->vertices[i].vertex=i+1;
10 g->vertices[i].head=NULL;
11 }
12 int start;
13 int end;
14 int weight;
15 for(int i=0;i<g->edge_num;++i)
16 {
17 cout <<"Enter two vertices and the weight in triple:";
18 cin >>start>>end>>weight;
19 Edge* link=new Edge;
20 link->adj_vertex=end;
21 link->next=g->vertices[start-1].head;
22 link->weight=weight;
23 g->vertices[start-1].head=link;
24 g->edges[i].u=start;
25 g->edges[i].v=end;
26 g->edges[i].weight=weight;
27 }
28 }

 

set
 1 //structure of the multiple sets
2 Vertex p[50];//each vertex's parent
3 int rank[50];//the rank
4
5 void Make_Set(Vertex x)
6 {
7 p[x.vertex-1]=x;
8 rank[x.vertex-1]=0;
9 }
10
11 Vertex Find_Set(Vertex x)
12 {
13 Vertex top=x;
14 while(top.vertex!=p[top.vertex-1].vertex)
15 top=p[top.vertex-1];
16 return top;
17 }
18
19 void Union(Vertex x,Vertex y)
20 {
21 Vertex p_x=Find_Set(x);
22 Vertex p_y=Find_Set(y);
23 if(rank[p_x.vertex-1]>rank[p_y.vertex-1])
24 p[p_y.vertex-1]=p_x;
25 else
26 {
27 p[p_x.vertex-1]=p_y;
28 if(rank[p_x.vertex-1]==rank[p_y.vertex-1])
29 rank[p_y.vertex-1]++;
30 }
31 }

 

heap sort
 1 //Heap Sort
2 void Maintain_Heap(Edge_MST* arr,int i,int n)
3 {
4 while(2*(i+1)<=n)
5 {
6 int left=2*(i+1)-1;
7 int right;
8 if(2*(i+1)<n)
9 right=2*(i+1);
10 else
11 right=left;
12 int largest=i;
13 if(arr[left].weight>arr[largest].weight)
14 largest=left;
15 if(arr[right].weight>arr[largest].weight)
16 largest=right;
17 Edge_MST tmp=arr[i];
18 arr[i]=arr[largest];
19 arr[largest]=tmp;
20 if(i==largest)
21 return;
22 else
23 i=largest;
24 }
25 }
26
27 void Build_Heap(Edge_MST* arr,int n)
28 {
29 int m=n/2-1;
30 for(;m>=0;--m)
31 Maintain_Heap(arr,m,n);
32 }
33
34
35 void Sort_Edges(Graph* g)
36 {
37 Build_Heap(g->edges,g->edge_num);
38 for(int i=g->edge_num-1;i>0;--i)
39 {
40 Edge_MST tmp=g->edges[0];
41 g->edges[0]=g->edges[i];
42 g->edges[i]=tmp;
43 Maintain_Heap(g->edges,0,i);
44 }
45 }

 

kruskal
 1 //edges in Minimum Spanning Tree
2 vector<Edge_MST> A;
3
4
5 //Kruskal
6 void Mst_Kruskal(Graph* g)
7 {
8 for(int i=0;i<g->vertex_num;++i)
9 Make_Set(g->vertices[i]);
10 Sort_Edges(g);
11 for(int i=0;i<g->edge_num;++i)
12 {
13 Edge_MST link=g->edges[i];
14 int u=link.u;
15 int v=link.v;
16 int set1=Find_Set(g->vertices[u-1]).vertex;
17 int set2=Find_Set(g->vertices[v-1]).vertex;
18 if(set1!=set2)
19 {
20 Union(g->vertices[u-1],g->vertices[v-1]);
21 A.push_back(link);
22 }
23 }
24 vector<Edge_MST>::iterator it=A.begin();
25 for(;it!=A.end();++it)
26 cout <<"Edge ("<<it->u<<","<<it->v<<") ";
27 }

 

posted @ 2012-02-21 21:21  Cavia  阅读(298)  评论(0编辑  收藏  举报