C++ Prim演算法構造可以使n個城市連線的最小生成樹
阿新 • • 發佈:2019-01-02
問題描述:給定一個地區的n個城市間的距離網,用Prim演算法建立最小生成樹,並計算得到的最小生成樹的代價。
基本要求:
1、城市間的距離網採用鄰接矩陣表示,若兩個城市之間不存在道路,則將相應邊的權值設為自己定義的無窮大值。(要求至少10個城市,15條邊)
2、最小生成樹中包括的邊及其權值,並顯示得到的最小生成樹的代價。
標頭檔案.h
// // MGraph.h // Prim_XCode // // Created by Holy-C on 14/12/22. // Copyright (c) 2014年 lyc. All rights reserved. // #ifndef MGraph_H #define MGraph_H #include <iostream> #include <iomanip> using namespace std; #define MaxSize 30 #define INFINITYN 65536 //表示權值無限大 struct shortEdge //輔助陣列 { int lowcost; int adjvex; }; template <class DataType> class MGraph { private: DataType vertex[MaxSize]; //存放頂點的陣列 int arcs[MaxSize][MaxSize]; //存放圖中邊的陣列 int versNum, arcsNum; //定點數和邊數 shortEdge shortEdge[MaxSize]; public: MGraph(); //初始化鄰接矩陣 ~MGraph(){} void CreateMGraph(); void printMGraph(); void Prim(); //Prim演算法生成最小生成樹 }; template <class DataType> MGraph<DataType>::MGraph() { cout << "請輸入頂點數和邊數:" << endl; cin >> versNum >> arcsNum; cout << "請輸入頂點字元資訊(" << versNum << "個):" << endl; for (int i = 0; i < versNum; i++) { cin >> vertex[i]; } for (int i = 0; i < versNum; i++) { for (int j = 0; j < versNum; j++) { if (i == j) arcs[i][j] = 0; else arcs[i][j] = INFINITYN; } } } template <class DataType> void MGraph<DataType>::CreateMGraph() { int i, j, w; cout << "請輸入邊<Vi,Vj>對應的頂點序號(" << arcsNum << "對),以及權值:" << endl; for (int k = 0; k < arcsNum; k++) { cin >> i >> j >> w; arcs[i][j] = w; arcs[j][i] = w; } } template <class DataType> void MGraph<DataType>::printMGraph() { cout << "鄰接矩陣為:" << endl; for (int i = 0; i < versNum; i++) { for (int j = 0; j < versNum; j++) { if (arcs[i][j] == 65536) cout <<" "<< setw(5) << "∞"; else cout << setw(5) << arcs[i][j]; } cout << endl; cout << endl; } } template <class DataType> void MGraph<DataType>::Prim() { int k, w, cost = 0; for (int i = 1; i < versNum; i++) { shortEdge[i].lowcost = arcs[0][i]; shortEdge[i].adjvex = 0; } shortEdge[0].lowcost = 0; for (int i = 1; i < versNum; i++) { w = INFINITYN; for (int j = 1; j < versNum; j++)/* 在輔助陣列closedge中選擇權值最小的頂點*/ { if (shortEdge[j].lowcost != 0 && shortEdge[j].lowcost < w) { w = shortEdge[j].lowcost; k = j; } /* 求出生成樹的下一個頂點k */ } shortEdge[k].lowcost = 0; for (int j = 1; j < versNum; j++) { if (arcs[k][j] < shortEdge[j].lowcost) { shortEdge[j].lowcost = arcs[k][j]; shortEdge[j].adjvex = k; } } } cout << "最小生成樹為:" << endl; for (int i = 1; i < versNum; i++) { cout << i << "->" << shortEdge[i].adjvex << "," << arcs[i][shortEdge[i].adjvex] << endl; cost = cost + arcs[i][shortEdge[i].adjvex]; } cout << "最小生成樹代價為:" << cost << endl; } #endif
以下是測試函式:
// // main.cpp // Prim_XCode // // Created by Holy-C on 14/12/22. // Copyright (c) 2014年 lyc. All rights reserved. // #include "MGraph.h" #include <iostream> using namespace std; int main() { MGraph<int> m1; m1.CreateMGraph(); m1.printMGraph(); m1.Prim(); }
測試資料: