題目描述:
傳送門與弱化版的單圈最短路徑題(即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,其餘點都標記為正無窮。我們要求出出發點到所有點的最短路徑,因此進行點數輪迴圈,每輪迴圈中,遍歷與已知點間有邊相連的點,更新與出發點的最短路徑。然後從所有更新...