1. 程式人生 > >C++ Prim演算法構造可以使n個城市連線的最小生成樹

C++ Prim演算法構造可以使n個城市連線的最小生成樹

問題描述:給定一個地區的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();  
}  


測試資料: