題目來自acwing
題目描述:
給定乙個n個點m條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為正值。
請你求出1號點到n號點的最短距離,如果無法從1號點走到n號點,則輸出-1。
輸入格式
第一行包含整數n和m。
接下來m行每行包含三個整數x,y,z,表示點x和點y之間存在一條有向邊,邊長為z。
輸出格式
輸出乙個整數,表示1號點到n號點的最短距離。
如果路徑不存在,則輸出-1。
資料範圍
1≤n≤500,
1≤m≤10^5,
圖中涉及邊長均不超過10000。
輸入樣例:
3 3
1 2 2
2 3 1
1 3 4
輸出樣例:3
時間複雜度:
dijkstra: o(n^2);
題目分析:
樸素dijkstra的方法很直觀,每次遍歷下所有的邊,找到點集外可加入點集的距離最小的點,加入到點集(點集中的點應確保是距離最短的)。再嘗試更新下新加入的點附近的點的距離。每次執行下找最短邊的操作時間複雜度是o(n),最壞情況下終點在最後才會被加入到點集,所以過程會被重複n次,故樸素的dijkstra演算法的時間複雜度為o(n^2)。
**如下:
#include
#include
using
namespace std;
const
int maxn =
510;
int n, m;
int g[maxn]
[maxn]
, d[maxn]
;bool vis[maxn]
;int
dijkstra()
vis[t]
=true
;for
(int j =
1;j <= n;j++)}
if(d[n]
==0x3f
)return-1
;return d[n];}
intmain()
cout <<
dijkstra()
<< endl;
return0;
}
對於稀疏圖問題,樸素dijkstra往往很難取得好結果,因此需要加以優化。我們利用優先佇列,實現堆優化的dijkstra。
**如下
來自
1 #include
2 #include
3 #include
4 #include
5using
namespace std;
6int n,m,s;
7int head[
100001
],dis[
100001
],cnt;
8bool vis[
100001];
9struct qwqedge[
200001];
13void
add(
int u,
int v,
int w)
1423
struct node29}
;30 priority_queue q;
31int
main()
3240
for(
int i=
1;i<=n;i++
)41 dis[i]
=2147483647
;42 dis[s]=0
;43 q.
push
(node);
44while
(!q.
empty()
)45);
57}58}
59}60for
(int i=
1;i<=n;i++)61
printf
("%d "
,dis[i]);
62return0;
63}
Dijkstra演算法求最短路 樸素版
圖論中求最短路的演算法有很多,這裡使用一道模板題來介紹可以求單源最短路的dijkstra演算法 acwing 849.dijkstra求最短路 i 求乙個源點到 除了這個點之外其他所有的點 的最短距離,不需要記錄每條路徑 這題一直困惑著我的是,為什麼一開始找的最小的最短距離就是確定的最短距離?想了好...
Dijkstra求最短路 I(樸素演算法)
給定乙個n個點m條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為正值。請你求出1號點到n號點的最短距離,如果無法從1號點走到n號點,則輸出 1。輸入格式 第一行包含整數n和m。接下來m行每行包含三個整數x,y,z,表示存在一條從點x到點y的有向邊,邊長為z。輸出格式 輸出乙個整數,表示1號點到n號...
Dijkstra求最短路
題目鏈結 給定乙個n個點m條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為正值。請你求出1號點到n號點的最短距離,如果無法從1號點走到n號點,則輸出 1。輸入格式 第一行包含整數n和m。接下來m行每行包含三個整數x,y,z,表示存在一條從點x到點y的有向邊,邊長為z。輸出格式 輸出乙個整數,表示1...