日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P4779 【模板】单源最短路径(标准版)

發布時間:2024/5/14 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P4779 【模板】单源最短路径(标准版) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

# 【模板】單源最短路徑(標準版)

## 題目背景

2018 年 7 月 19 日,某位同學在 [NOI Day 1 T1 歸程](https://www.luogu.org/problemnew/show/P4768) 一題里非常熟練地使用了一個廣為人知的算法求最短路。

然后呢?

$100 \rightarrow 60$;

$\text{Ag} \rightarrow \text{Cu}$;

最終,他因此沒能與理想的大學達成契約。

小 F 衷心祝愿大家不再重蹈覆轍。

## 題目描述

給定一個 $n$ 個點,$m$ 條有向邊的帶非負權圖,請你計算從 $s$ 出發,到每個點的距離。

數據保證你能從 $s$ 出發到任意點。

## 輸入格式

第一行為三個正整數 $n, m, s$。
第二行起 $m$ 行,每行三個非負整數 $u_i, v_i, w_i$,表示從 $u_i$ 到 $v_i$ 有一條權值為 $w_i$ 的有向邊。

## 輸出格式

輸出一行 $n$ 個空格分隔的非負整數,表示 $s$ 到每個點的距離。

## 樣例 #1

### 樣例輸入 #1

```
4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
```

### 樣例輸出 #1

```
0 2 4 3
```

## 提示

樣例解釋請參考 [數據隨機的模板題](https://www.luogu.org/problemnew/show/P3371)。

$1 \leq n \leq 10^5$;

$1 \leq m \leq 2\times 10^5$;

$s = 1$;

$1 \leq u_i, v_i\leq n$;

$0 \leq w_i \leq 10 ^ 9$,

$0 \leq \sum w_i \leq 10 ^ 9$。

本題數據可能會持續更新,但不會重測,望周知。

2018.09.04 數據更新 from @zzq

1.這個問題用dijkstra算法即可,要使用堆優化的dijkstra算法,否則會時間超限。

2.剛開始我是想自己手寫一個堆,模擬優先隊列,然而修修改改還是只是AC了倆個點 ,沒辦法去學了C++里面的STL里的優先隊列。

3.繼而就簡單多了(代碼少了將近一大半)

4.堆優化的dijkstra算法也是非常簡單,核心思想是一樣的,先松弛,再找最近的那一個點,繼續松弛循環下去。用堆來實現就是把新更新的距離權值入隊,然后在優先隊列里面會自動在首元素是最小值了。我們只需要判斷堆頂元素是否訪問過即可,如果訪問過了,就彈出堆頂元素,繼續找就可以。

while( !q.empty() )//如果隊列不為空,就需要繼續訪問{tmp = q.top();//訪問堆頂元素q.pop();//彈出隊頭x = tmp.pos, w = tmp.w;if( book[x] )continue;//如果該點已經納入最短路徑,需要跳過book[x] = 1;//從該點開始松弛for(i = head[x]; i; i = e[i].next )//鏈式前向星{y = e[i].to;if( dis[y] > dis[x] + e[i].w ){dis[y] = dis[x] + e[i].w;if( !book[y] ){q.push( ( node ){dis[y], y} );//插入元素并且重新排序}}}}

完整C++代碼如下:

#include<iostream> #include<bits/stdc++.h> #include<cstdio> #include<algorithm>using namespace std;const int N = 100010, M = 500010; const int INF=1000000000; struct edges {int to;int w;int next; }e[M]; int head[N], dis[N]; bool book[N]; int n, m, s; struct node {int w;int pos;bool operator <( const node &x )const{return x.w <w;} }; priority_queue<node> q;//建立堆 void dijk() {int i,y,x,w;node tmp;dis[s] = 0;q.push( ( node ){0, s} );//放入該節點,也就是入隊while( !q.empty() )//如果隊列不為空,就需要繼續訪問{tmp = q.top();//訪問堆頂元素q.pop();//彈出隊頭x = tmp.pos, w = tmp.w;if( book[x] )continue;//如果該點已經納入最短路徑,需要跳過book[x] = 1;//從該點開始松弛for(i = head[x]; i; i = e[i].next )//鏈式前向星{y = e[i].to;if( dis[y] > dis[x] + e[i].w ){dis[y] = dis[x] + e[i].w;if( !book[y] ){q.push( ( node ){dis[y], y} );//插入元素并且重新排序}}}}for( i = 1; i <= n; i++ )printf( "%d ", dis[i] ); } int main() {int i,u,v,w;scanf( "%d%d%d", &n, &m, &s );for(i = 1; i <= n; i++) dis[i] =INF;for(i = 1; i <= m; i++){scanf( "%d%d%d", &u, &v, &w );e[i].to=v;e[i].w=w;e[i].next=head[u];head[u]=i;}dijk();return 0; }

總結

以上是生活随笔為你收集整理的P4779 【模板】单源最短路径(标准版)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。