貪心——Prim算法(避圈法)


1.簡介

  Prim算法是圖論中的一種算法,可在帶權連通圖里搜索產生最小生成樹。

  該算法於1930年由捷克數學家沃伊捷赫·亞爾尼克(Vojtěch Jarník)發現;並在1957年由美國計算機科學家羅伯特·普里姆(Robert C. Prim)獨立發現;1959年,艾茲格·迪科斯徹再次發現了該算法。

  Prim算法從任意一個頂點開始,每次選擇一個與當前頂點集最近的一個頂點,並將兩頂點之間的邊加入到樹中,在找當前最近頂點時使用到了貪心算法。

  預備知識(了解的跳過):

  無向圖鄰接矩陣最小生成樹

2.實例

  先給出一個這樣的鄰接矩陣,找最小生成樹吧:

  把鄰接矩陣可以翻譯成這樣的無向圖:

  過程:

 

  Prim算法是基於節點做優先考慮的,以某一節點開始作為根節點,不斷搜索距離的權值最小的節點,然后加入到生成樹中。

3.代碼

#include<bits/stdc++.h>
#define INF 99999
using namespace std;
const int N = 6;
bool visit[N];
int dist[N] = { 0, };
int graph[N][N] = { {0,6,1,5,INF,INF},  //INF代表兩點之間不可達
                    {6,0,5,INF,3,INF},
                    {1,5,0,5,6,4},
                    {5,INF,5,0,INF,2},
                    {INF,3,6,INF,0,6},
                    {INF,INF,4,2,6,0}
                  };
int prim(int cur){
    int index = cur;
    int sum = 0,i = 0,j = 0;
    cout << index << " ";
    memset(visit,false, sizeof(visit));
    visit[cur] = true;
    for(i = 0; i < N; i++)
        dist[i] = graph[cur][i];//初始化,每個與a鄰接的點的距離存入dist
    for(i = 1; i < N; i++){
        int minor = INF;
        for(j = 0; j < N; j++){
            if(!visit[j] && dist[j] < minor){   //找到未訪問的點中,距離當前最小生成樹距離最小的點
                minor = dist[j];
                index = j;
            }
        }
        visit[index] = true;
        cout << index << " ";
        sum += minor;
        for(j = 0; j < N; j++){
            if(!visit[j] && dist[j]>graph[index][j])      //執行更新,如果點距離當前點的距離更近,就更新dist
            {
                dist[j] = graph[index][j];
            }
        }
    }
    cout<<endl;
    return sum;               //返回最小生成樹的總路徑值
}
int main(){
    cout << prim(0) << endl;//從頂點a開始
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM