算法筆記---Prim算法

Prim算法:用來解決最小生成樹的問題
Prim算法和Dijkstra算法思想類似,都是採用貪心的思想。
兩個算法的主要區別:

  1. Dijkstra算法的dis[]數組是記錄未訪問結點集合與源結點的最短路徑,而Prim算法的dis[]數組記錄的是未訪問結點集合到已訪問結點結合的最短距離。
    兩個算法都是用bool visited[]數組來表示當前結點是否被訪問。

  2. Prim算法有一個統計最小生成樹的總的最短距離len,每次訪問一個距離最短的結點,都要將該最短邊加上len,而Dijkstra算法則沒有該變量。

  3. Prim算法是求解最小生成樹的算法,比如用來求解N個村莊之間修路的最小花費,而Dijkstra算法是求解單源最短路徑的算法,比如求解某一個村莊到所有村莊的最短路徑。

算法的具體步驟:

1、除了指定根結點外,其他的結點的dis[]都設置爲INF(無窮大)
2、遍歷n次,n爲圖中的結點數。每次都找出未被訪問結點距離已訪問結點集合的最小值。
3、遍歷當前結點所鄰接的未被訪問的邊,如果以當前結點作爲中介點,使得其鄰接點到已訪問集合的距離更短。則更新距離。

樣例:

輸入:
6 10//6個頂點,10條邊。以下10行爲10條邊
0 1 4//邊0->1與1->0的邊權爲4,下同
0 4 1
0 5 2
1 2 6
1 5 3
2 3 6
2 5 5
3 4 4
3 5 5
4 5 3
輸出:
15

下面爲實現代碼:

#include <iostream>
#include <algorithm>
using namespace std;

const int prim_max_num = 1000;
const int INF = 1000000000;
int n, m, G[prim_max_num][prim_max_num];
int dis[prim_max_num]; //頂點與集合S的最短距離
bool visited[prim_max_num] = {false};

//求出最小生成樹的最短距離
int prim()
{
    //默認根結點爲 0
    fill(dis, dis + prim_max_num, INF); //初始化 dis 數組
    dis[0] = 0;
    int result = 0;
    for (int i = 0; i < n; i++)
    {                   //共有 n 個結點
        int index = -1; //最短路徑結點的下標
        int min = INF;
        for (int j = 0; j < n; j++)
        {
            if (visited[j] == false && dis[j] < min)
            {
                index = j;
                min = dis[j];
            }
        }
        //找不到最小結點
        if (index == -1)
        {
            return -1;
        }
        visited[index] = true;
        result += dis[index];
        for (int k = 0; k < n; k++)
        {
            if (visited[k] == false && G[index][k] != INF && G[index][k] < dis[k])
            {
                dis[k] = G[index][k];
            }
        }
    }
    return result;
}

int main()
{
    cin >> n >> m;
    fill(G[0], G[0] + prim_max_num * prim_max_num, INF);
    int from_node, to_node, weight;
    for (int i = 0; i < m; i++)
    {
        cin >> from_node >> to_node >> weight;
        G[from_node][to_node] = G[to_node][from_node] = weight;
    }
    int result = prim();
    cout << result << endl;//輸出最短距離
    system("pause");
    return 0;
}

運行結果:
運行結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章