題目
給出一個有向圖,請輸出從某一點出發到所有點的最短路徑長度。
輸入格式
第一行包含三個整數 n , m , s 分別表示點的個數、有向邊的個數、出發點的編號。
接下來 m 行每行包含三個整數 u , v , w 表示一條u→v 的,長度爲 w 的邊。
輸出格式
輸出一行 n 個整數,第 i 個表示 s 到第 i 個點的最短路徑,若不能到達則輸出 231-1
輸入輸出樣例
輸入
4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
輸出
0 2 4 3
洛谷測試平臺
-
SPFA 算法
Bellman-Ford算法的隊列優化算法的別稱,通常用於求含負權邊的單源最短路徑,以及判負權環。SPFA 最壞情況下複雜度爲 O(NM)。 -
迪傑斯特拉算法
由荷蘭計算機科學家 狄克斯特拉於1959 年提出的,因此又叫 狄克斯特拉算法。是從一個頂點到其餘各頂點的 最短路徑算法,解決的是有向圖中最短路徑問題。迪傑斯特拉算法主要特點是以起始點爲中心向外層層擴展,直到擴展到終點爲止。 迪傑斯特拉算法 最壞情況下複雜度爲 O(NM)。可用堆進行優化,優化後O(( m+ n)log n)。(不可判負權環)
本題測試數據較小,可直接採用 spfa +鄰接表解決。
關鍵點
- 創建結構體數組
①、存儲第 i 個城市到達 s 城市的最短路徑。
②、存儲第 i 個城市可到達的(多個)城市標號及路徑長度。 - spfa算法——隊列
①、將可能爲最短路徑的城市插入隊列中。
若 i 城市到 j 城市路徑長度 + 第 i 城市到第 s 城市最短路徑 <= j 城市到第 s 城市最短路徑,則不必將 j 城市放入隊列。
#include<bits/stdc++.h>
using namespace std;
struct node1{
int len; //第i個城市的路徑長度
int end; //通往的城市標號
}tmp;
struct node{
vector <node1> next; //第i個城市能通往的城市信息
int min_dis; //第i個城市通往s的最短路徑
}N[10010];
void bfs(int a){
queue <int> q;
q.push(a);
while(!q.empty()){
int top = q.front();
q.pop();
for(int i=0; i<N[top].next.size(); i++){
int v=N[top].next[i].end;
//若第v個城市離s城市有更短的路徑
//則更改第v個城市到s城市的最短路徑且將v入隊
if(N[v].min_dis>N[top].min_dis+N[top].next[i].len){
N[v].min_dis=N[top].min_dis+N[top].next[i].len;
q.push(v);
}
}
}
}
int main(){
int n, m, s;
cin>>n>>m>>s;
for(int i=1; i<=n; i++){
N[i].min_dis= (1<<31)-1;
}
for(int i=0; i<m; i++){
int u, v, w;
cin>>u>>v>>w;
tmp.end=v;
tmp.len=w;
N[u].next.push_back(tmp);
}
N[s].min_dis=0;
bfs(s);
for(int i=1; i<=n; i++){
cout<<N[i].min_dis<<" ";
}
return 0;
}
若文章對你有幫助,可以留個贊麼