開發設計文件資訊軟體
我們之前介紹的求最短路問題,我們通常會考慮到用BFS演算法計算,這裡我們將這樣對於求最短路問題用不同的演算法進行分類:
思路介紹:Dijkstra演算法的思路究竟是怎麼樣的,我們這裡先介紹一下樸素版Dijkstra演算法的思路:
因為我們要去計算的是每個節點到起始點的最短距離,所以我們使用的方法是不斷地迭代更新數值,我們會利用一個st陣列(state)來表示每個結點的狀態,我們保證的是如果st【i】 = true了,那麼我們就可以說dist【i】儲存的就是從這個點到起始點的最短距離了,所以為了保證每一個節點都能夠被保證其最小值,我們需要在外層迴圈n次,然後在內迴圈中,我們先去定義一個t,t這個節點指的是目前到起始點最近的點,然後我們從這個點出發去更新他能直接走到的所有的點的位置,但是值得注意的是,我們從當前的點走到的下一個點所得出的dist不一定就是最小的情況,比如下圖的情況:
我們可以發現,第一個t是1點,從點1出發能更新到2,3兩個點,但是此時的dist[3] =3,很明顯不是最小的,所以我們下一個t值是2,從點2開始走,更新點3,所以我們要用到min函式;
程式碼:
#include<bits/stdc++.h>
#define maxn 510
using namespace std;
int G[maxn][maxn] , dist[maxn],n,m;
bool st[maxn];
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] && (t == -1 || dist[j] < dist[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;
else return dist[n];
}
int main()
{
memset(G,0x3f,sizeof(G));
cin >> n >> m;
while (m -- ){
int x , y , z;
cin >> x >> y >> z;
G[x][y] = min(G[x][y],z);
}
int ans = dijkstra();
cout << ans;
return 0;
}
分析:
·首先,我們解釋一下G陣列,這是個鄰接矩陣,這也是一種常見的儲存樹和圖之間關係的方式,與鄰接表不同的是,這個通常用於儲存比較稠密的圖,二鄰接表通常用於儲存比較稀疏的圖;
·我們發現我們把G陣列和dist陣列都先初始化為0x3f3f3f3f,這是為了之後我們在更新數值的時候不會更新那些我們無法從當前的節點走到的節點;
因為可以發現,我們用鄰接矩陣儲存圖,我們不能直接的找到他能走到的下一個節點,所以我們是通過一股腦的遍歷所有元素來取最小值,我們會發現如果兩者之間沒有直接的聯絡,G[t][j] + dist[t] > 0x3f3f3f3f = dist[j];