1. 程式人生 > 其它 >[ABC061D]Score Attack/「模板」Bellman-ford 演算法

[ABC061D]Score Attack/「模板」Bellman-ford 演算法

做了這題我發現

  1. 我不懂單源最短路。
  2. BF 還是有用的。

給出有向圖,求單源最長路,或指出有環。

開始時覺得這不是直接寫個 spfa 記錄一下每個點更新次數解決?然後就 WA 了。
其實這是一個嚴重的歷史遺留問題,即學習最短路演算法時不經 BF 直接學習並記下 SPFA
首先,WA 是很顯然的,比如下面這幅圖。

出現環了不代表在到 \(n\) 的路上一定有。那難道要找出每個環上的點並一一判斷是否在到 \(n\) 的路徑上嗎?其實並不是,只需要對程式碼進行小小的改動就可以了。

先回到 BF,BF 的流程是這樣的:

  1. 迭代 \(n-1\) 次。
  2. 每一次嘗試鬆弛每條邊。

\[\boxed{ \begin{aligned} \text{Be}&\text{llman-Ford 虛擬碼}\\ \hline 1.\ &\text{for } i = 1 \to n-1 \\ 2.\ & \kern{2em}\text{for } j = 1 \to m \\ 3.\ & \kern{4em} d_{v_j} = \min\{d_{v_j}, d_{u_j} + l_j\}\\ \end{aligned} } \]

其實感性理解一下十分的簡單,就是一個 dp 的思想,因為每個路徑不可能有超過 \(n-1\)

條邊,而每次進行一次迭代時會讓最短路延長上 \(1\),所以迭代 \(n-1\) 次就可以出結果了。

那麼如何判環呢?很簡單,如果再來一次某個點的最短路又雙叒叕被更新了,那麼在前往其的路徑上肯定有一個環。注意,是前往其的路徑上有一個環

未完待續。