1. 程式人生 > 其它 >2.3搜尋與圖論(最短路)

2.3搜尋與圖論(最短路)

1.樸素Dijkstra演算法

稠密圖用鄰接矩陣,稀疏圖用鄰接表存

1≤m≤10^5,所以顯然這是個稠密圖,由於圖中可能存在重邊和自環,於是我們用g[N][N]儲存每條邊的距離時,先要將其初始化為無窮,然後讀取時比較一下其與原陣列中的值的大小,取最小值儲存。Dijkstra方法中,對於每個數都迴圈一次,先找到沒有找到過的距離1點最近的點,把它的st陣列中的值設為真,然後遍歷所有數更新其距離。

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

const int N = 510;
int g[N][N] , dist[N];//g[i][j]儲存i到j的距離,dist表示每個點到1的距離
int n , m;
bool st[N];//表示每個點是否能確定到1的距離

int dijkstra()
{
    memset(dist , 0x3f , sizeof dist);
    dist[1] = 0;
    for (int i = 0 ; i < n; i ++)
    {
        int t = -1;
        for (int j = 1 ; j <= n ; j++)
        {
            if(!st[j] and (t = -1 or dist[j] < dist[t]))//j沒有確定最短路並且(t沒有複製或者t並不是最短的)
                t = j;
        }
        st[t] = true;
        for (int j = 1 ; j <= n ; j++)
        {
            dist[j] = min(dist[j] , dist[t] + g[t][j]);
        }
    }
    if(dist[n]==0x3f3f3f3f) return -1;
    return dist[n];
}

int main()
{
    cin >> n >> m;
    memset(g , 0x3f , sizeof g);//初始化成很大的數
    while (m--)
    {
        int a , b , c;
        scanf("%d%d%d" , &a , &b , &c);
        g[a][b] = min(c , g[a][b]);
    }
    cout << dijkstra() <<endl;
    return 0;
}