1+ #include < iostream>
2+ #include < vector>
3+ #include < queue>
4+ #include < algorithm>
5+ using namespace std ;
6+ #define INF 0x3f3f3f3f
7+ #define VertexData int // 顶点数据
8+ #define UINT int
9+ #define vexCounts 6 // 顶点数量
10+ char vextex[] = { ' A' , ' B' , ' C' , ' D' , ' E' , ' F' };
11+ struct node
12+ {
13+ VertexData data;
14+ int lowestcost;
15+ }closedge[vexCounts]; // Prim算法中的辅助信息
16+ typedef struct
17+ {
18+ VertexData u;
19+ VertexData v;
20+ int cost; // 边的代价
21+ }Arc; // 原始图的边信息
22+ void AdjMatrix (int adjMat[][vexCounts]) // 邻接矩阵表示法
23+ {
24+ for (int i = 0 ; i < vexCounts; i++) // 初始化邻接矩阵
25+ for (int j = 0 ; j < vexCounts; j++)
26+ {
27+ adjMat[i][j] = INF;
28+ }
29+ adjMat[0 ][1 ] = 6 ; adjMat[0 ][2 ] = 1 ; adjMat[0 ][3 ] = 5 ;
30+ adjMat[1 ][0 ] = 6 ; adjMat[1 ][2 ] = 5 ; adjMat[1 ][4 ] = 3 ;
31+ adjMat[2 ][0 ] = 1 ; adjMat[2 ][1 ] = 5 ; adjMat[2 ][3 ] = 5 ; adjMat[2 ][4 ] = 6 ; adjMat[2 ][5 ] = 4 ;
32+ adjMat[3 ][0 ] = 5 ; adjMat[3 ][2 ] = 5 ; adjMat[3 ][5 ] = 2 ;
33+ adjMat[4 ][1 ] = 3 ; adjMat[4 ][2 ] = 6 ; adjMat[4 ][5 ] = 6 ;
34+ adjMat[5 ][2 ] = 4 ; adjMat[5 ][3 ] = 2 ; adjMat[5 ][4 ] = 6 ;
35+ }
36+ int Minmum (struct node * closedge) // 返回最小代价边
37+ {
38+ int min = INF;
39+ int index = -1 ;
40+ for (int i = 0 ; i < vexCounts;i++)
41+ {
42+ if (closedge[i].lowestcost < min && closedge[i].lowestcost !=0 )
43+ {
44+ min = closedge[i].lowestcost ;
45+ index = i;
46+ }
47+ }
48+ return index;
49+ }
50+ void MiniSpanTree_Prim (int adjMat[][vexCounts], VertexData s)
51+ {
52+ for (int i = 0 ; i < vexCounts;i++)
53+ {
54+ closedge[i].lowestcost = INF;
55+ }
56+ closedge[s].data = s; // 从顶点s开始
57+ closedge[s].lowestcost = 0 ;
58+ for (int i = 0 ; i < vexCounts;i++) // 初始化辅助数组
59+ {
60+ if (i != s)
61+ {
62+ closedge[i].data = s;
63+ closedge[i].lowestcost = adjMat[s][i];
64+ }
65+ }
66+ for (int e = 1 ; e <= vexCounts -1 ; e++) // n-1条边时退出
67+ {
68+ int k = Minmum (closedge); // 选择最小代价边
69+ cout << vextex[closedge[k].data ] << " --" << vextex[k] << endl;// 加入到最小生成树
70+ closedge[k].lowestcost = 0 ; // 代价置为0
71+ for (int i = 0 ; i < vexCounts;i++) // 更新v中顶点最小代价边信息
72+ {
73+ if ( adjMat[k][i] < closedge[i].lowestcost )
74+ {
75+ closedge[i].data = k;
76+ closedge[i].lowestcost = adjMat[k][i];
77+ }
78+ }
79+ }
80+ }
81+ void ReadArc (int adjMat[][vexCounts],vector<Arc> &vertexArc) // 保存图的边代价信息
82+ {
83+ Arc * temp = NULL ;
84+ for (int i = 0 ; i < vexCounts;i++)
85+ {
86+ for (int j = 0 ; j < i; j++)
87+ {
88+ if (adjMat[i][j]!=INF)
89+ {
90+ temp = new Arc;
91+ temp->u = i;
92+ temp->v = j;
93+ temp->cost = adjMat[i][j];
94+ vertexArc.push_back (*temp);
95+ }
96+ }
97+ }
98+ }
99+ bool compare (Arc A, Arc B)
100+ {
101+ return A.cost < B.cost ? true : false ;
102+ }
103+ bool FindTree (VertexData u, VertexData v,vector<vector<VertexData> > &Tree)
104+ {
105+ int index_u = INF;
106+ int index_v = INF;
107+ for (int i = 0 ; i < Tree.size ();i++) // 检查u,v分别属于哪颗树
108+ {
109+ if (find (Tree[i].begin (), Tree[i].end (), u) != Tree[i].end ())
110+ index_u = i;
111+ if (find (Tree[i].begin (), Tree[i].end (), v) != Tree[i].end ())
112+ index_v = i;
113+ }
114+
115+ if (index_u != index_v) // u,v不在一颗树上,合并两颗树
116+ {
117+ for (int i = 0 ; i < Tree[index_v].size ();i++)
118+ {
119+ Tree[index_u].push_back (Tree[index_v][i]);
120+ }
121+ Tree[index_v].clear ();
122+ return true ;
123+ }
124+ return false ;
125+ }
126+ void MiniSpanTree_Kruskal (int adjMat[][vexCounts])
127+ {
128+ vector<Arc> vertexArc;
129+ ReadArc (adjMat, vertexArc);// 读取边信息
130+ sort (vertexArc.begin (), vertexArc.end (), compare);// 边按从小到大排序
131+ vector<vector<VertexData> > Tree (vexCounts); // 6棵独立树
132+ for (int i = 0 ; i < vexCounts; i++)
133+ {
134+ Tree[i].push_back (i); // 初始化6棵独立树的信息
135+ }
136+ for (int i = 0 ; i < vertexArc.size (); i++)// 依次从小到大取最小代价边
137+ {
138+ VertexData u = vertexArc[i].u ;
139+ VertexData v = vertexArc[i].v ;
140+ if (FindTree (u, v, Tree))// 检查此边的两个顶点是否在一颗树内
141+ {
142+ cout << vextex[u] << " ---" << vextex[v] << endl;// 把此边加入到最小生成树中
143+ }
144+ }
145+ }
146+
147+ int main ()
148+ {
149+ int adjMat[vexCounts][vexCounts] = { 0 };
150+ AdjMatrix (adjMat); // 邻接矩阵
151+ cout << " Prim :" << endl;
152+ MiniSpanTree_Prim (adjMat,0 ); // Prim算法,从顶点0开始.
153+ cout << " -------------" << endl << " Kruskal:" << endl;
154+ MiniSpanTree_Kruskal (adjMat);// Kruskal算法
155+ system (" pause" );
156+ return 0 ;
157+ }
0 commit comments