最短路徑dijkstra模板

題目描述

第一行兩個整數n m。n表示頂點個數(頂點編號爲1~n),m表示邊的條數。接下來m行表示,每行有3個數x y z。表示頂點x到頂點y邊的權值爲z。求源點爲1的最短路徑。
題目來源【坐在馬桶上看算法】算法7:Dijkstra最短路算法

題目思路

這道題我只是想練練dijkstra模板,dijkstra主要由兩個步驟組成:

  • 找到頂點 i 周圍距離最近的點 u
  • u 加入集合(已確定最短路徑的點的集合)
  • 利用u更新其他所有的點到源點的最短路徑距離

代碼

#include <iostream>
#include <stdio.h>
using namespace std;
#define inf 0x3f3f3f3f
#define max 100
//edge[i][j]記錄i到j的邊長,dis[i]記錄到i的最短路徑長,
//mask[i]記錄i點是否加入集合,pre[i]記錄i的最短路徑上i的前一個點 
int edge[max][max],dis[max],mask[max],pre[max];
int main() {
    freopen("in.txt","r",stdin);
    int n,m;
    cin>>n>>m;
    //初始化edge[][],默認點到自己的邊長爲0,其他的默認爲inf,即不可達 
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==j) {
                edge[i][j]=0;
            }
            else {
                edge[i][j]=inf;
            }
        }
    }
    //輸入邊長 
    int a,b,w;
    for(int i=1;i<=m;i++){
        cin>>a>>b>>w;
        edge[a][b]=w;
    }
    //源點爲1,所以看1周圍的點(沒有和1相鄰的點距離會是inf) 
    for(int i=1;i<=n;i++){
        dis[i]=edge[1][i];//在這裏用邊去初始化距離 
        mask[i]=0;
        pre[i]=1;
    }
    mask[1]=1;//1爲源點,讓1被訪問過 
    //dijkstra核心操作如下 
    for(int i=1;i<=n-1;i++){
        int min=inf;
        int u;
        //每一次選出和i最近的點u,加入集合(每次只選一個) 
        for(int j=1;j<=n;j++){
            if(mask[j]==0&&min>dis[j]){
                min=dis[j];
                u=j;
            }
        }
        //u加入集合 
        mask[u]=1;
        //根據u去更新其他點到源點的距離,因爲可能經過u中轉之後有的點和源點會更近(所以遍歷所有點) 
        for(int v=1;v<=n;v++){
            if(dis[v]>dis[u]+edge[u][v]){
                dis[v] = dis[u]+edge[u][v];
                pre[v]=u;//以u爲中轉的話,v到源點的最短路徑上v的前一個點就是u 
            }

        }
    }
    //輸出最短路徑長度結果 
    for(int i=1;i<=n;i++){
        cout<<dis[i]<<" ";
    }
    cout<<endl;
    //輸出最短路徑 
    for(int i=1;i<=n;i++){
        int nn=i;
        while(nn!=1){
            cout<<nn<<"-";
            nn=pre[nn];
        }
        cout<<"1"<<endl;
    }
    fclose(stdin);
    return 0;
}

輸入:
6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
輸出:
0 1 8 4 13 17
1
2-1
3-4-2-1
4-2-1
5-3-4-2-1
6-5-3-4-2-1

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