847. Shortest Path Visiting All Nodes(三)
DP
這道題目還可以用動態(tài)規(guī)劃解決。在圖論中解決最短路徑問題有Dijkstra算法和bellman-ford算法。這道題目也需要用到DP。所以先學(xué)習(xí)一下這兩個算法的思想和區(qū)別。
兩個算法比較
Dijstra算法用來解決單源最短路徑問題。具體內(nèi)容看[文章]
| Dijkstra算法 | 單源最短路徑 | 權(quán)重是正的圖 | 貪心 | 頂點 |
| bellman-ford算法 | 單源最短路徑 | 圖,不可以有負(fù)權(quán)環(huán)路 | 動態(tài)規(guī)劃 | 邊 |
ps:雖然我也不明白為什么叫松弛。只知道是不斷處理,不斷優(yōu)化的對象。
之所以做比較是想明白這兩個算法有什么區(qū)別。以及第二個算法的思想是怎么應(yīng)用在本題目。
本題目的DP方案參考鏈接。
首先使用Floy算法計算任意兩點之間的最短路徑。接著使用遞歸方程dp[i][j] = Math.min(dp[i][j],dp[包含u但是不包含v 的狀態(tài)][u]+dist[u][v])。
代碼
關(guān)于FLoyd算法的介紹參考文章。
用二維數(shù)組記錄任意兩點之間的距離。dis[i][j]表示從i節(jié)點到j(luò)節(jié)點的距離。如果這兩點之間有邊,則dis的初始值是邊的權(quán)重,否則是無窮大。
如果要讓兩點之間(例如a,b)的路程變短,那只能引入第三點(k)。如果a->k->b的距離小于a->b的距離,那就引入k。有時候可能需要引入不止一個節(jié)點,才能找到ab之間的最短路徑:a->k1->k2…->b。每個頂點可能使得另外兩個節(jié)點路程變短。
第二步,如果允許在所有節(jié)點之間跨越節(jié)點1。如果dis[i][1]+dis[1][j]<dis[i][j]dis[i][1]+dis[1][j]<dis[i][j]dis[i][1]+dis[1][j]<dis[i][j],那么dis[i][j]=dis[i][1]+dis[1][j]dis[i][j]=dis[i][1]+dis[1][j]dis[i][j]=dis[i][1]+dis[1][j]。需要用兩個for循環(huán)實現(xiàn)替換。
第三步,如果允許在所有節(jié)點之間跨越節(jié)點1、2。如何做呢?我們需要在只允許經(jīng)過1號頂點時任意兩點的最短路程的結(jié)果下,再判斷如果經(jīng)過2號頂點是否可以使得i號頂點到j(luò)號頂點之間的路程變得更短。即判斷e[i][2]+e[2][j]是否比e[i][j]要小。
第四步,進(jìn)一步計算允許跨越節(jié)點1,2,3…,一直到節(jié)點n。最后的代碼就是:
總結(jié)
以上是生活随笔為你收集整理的847. Shortest Path Visiting All Nodes(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 五大常用算法实例列举
- 下一篇: 风格迁移篇---SAnet:风格注意网络