單源最短路徑(標準版)

2022-08-17 15:27:14 字數 1481 閱讀 1431

題目描述:

傳送門與弱化版的單圈最短路徑題(即p3371)的題目比較,主要有兩個不同點(其他的基本不變):

1.此題中說明了所給的測試資料能保證起始點訪問到所有的點

2.很明顯,這個題的時間限制更加嚴格

題解:因此要解決此題,我們可以再p3371的基礎上(**鏈結)進行修改+優化,即可達到此題的要求。

針對於不同點1,p3371的基礎上將if(color[j]==black||a[u][j]==0) continue;改為了if(color[j]==black) continue; 因為題目已經***了,沒必要判斷不同點之間是否有邊連線,反而這個操作會限制本來有邊連線(但權值沒來得及更新仍然為0)的後續更新,因此此處去掉。

針對於不同點2,採用3個優化操作:(儲存結構依然用前向星)

①在遍歷變數的時候採取register int,加快速度,減少tle的出現概率。register int的具體解釋見:這裡

②在各節點出隊的時候加上if(color[u]==black) continue;來減少點重複出隊

最關鍵的點:採用堆排序或者是優先佇列,將o(n^2)的複雜度降到o(nlogn)。即在每次尋找距離源點的最小節點部分,採用優先佇列(最小堆)來代替,優化此處操作。

1 #include2

#define re register

3using

namespace

std;

4int max=100005;5

int infty=2147483647;6

int white=0;7

int black=1;8

int gray=2;9

intn,m,s;

10 typedef pairp;

11struct

edgee[500010

];16

int head[100005]; //

head[i]表示與i所有相連線的邊中第一條邊的編號

17int cnt=0; //

代表邊的編號從0開始

1819

//鄰接矩陣+優先佇列

20//

使用了優先佇列 便省去了找當前最小權值點的步驟 因為最小值始終在隊頭

21void

dijkstra()

31 d[s]=0;32

33 pq.push(make_pair(0

,s));

34 color[s]=gray;

3536

while(!pq.empty())54}

55}56for(re int i=1;i<=n;i++)59}

60void add(int u,int v,int

w) 67

intmain()

7576

dijkstra();

77return0;

78 }

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

題目背景 2018 年 7 月 19 日,某位同學在 noi day 1 t1 歸程 一題裡非常熟練地使用了乙個廣為人知的演算法求最短路。然後呢?100 rightarrow 60100 60 ag rightarrow cuag cu 最終,他因此沒能與理想的大學達成契約。小 f 衷心祝願大家不再...

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

題目鏈結 給定乙個 n 個點,m 條有向邊的帶非負權圖,請你計算從 s 出發,到每個點的距離。資料保證你能從 s 出發到任意點。第一行為三個正整數 n,m,s。第二行起 m 行,每行三個非負整數 ui,vi,wi,表示從 ui 到 vi 有一條權值為 wi 的有向邊。輸出一行 n 個空格分隔的非負整...

P4779單源最短路徑(標準版)

應用的是dijkstra演算法,這種演算法的思想類似於貪心。首先,將所有點分為已知最短路和未知最短路兩類。開始時,只有出發點的最短路已知,為0,其餘點都標記為正無窮。我們要求出出發點到所有點的最短路徑,因此進行點數輪迴圈,每輪迴圈中,遍歷與已知點間有邊相連的點,更新與出發點的最短路徑。然後從所有更新...