dag就是有向無環圖。
dag上的最長或者最短路是很重要的一類問題。很多問題都可以轉化為dag上的最長或者最短路徑的問題。dag求最短和最長路的方法一樣。
本演算法主要解決2個問題
1)求整個dag中的最長路徑(即不固定起點,也不固定終點)
2)固定終點,求dag的最長路徑。
dp【i】表示從i 號頂點出發能獲得的最長路徑的長度int dp(int i)
for(int j = 0; j < n; j++)
} return dp[i];
}
入度為0的頂點出發最長路徑長度就0,這就遞迴邊界。
但是我們實際寫的時候不妨對整個dp陣列進行初始化為0,這樣當dp函式訪問的頂點i的出度為0的時候就會返回值0.(以此作為遞迴邊界)。而出度不為0的就會自動遞迴求解。遞迴過程中,遇到已經計算過的頂點則直接返回對應的dp值,於是從程式邏輯上按照逆拓撲排序進行。
求路徑
int dp(int i)
} return dp[i]; }}
void printpath(int i)
}
如果有多條路徑開個vector陣列即可,並且 這個是自動按字典序最小輸出的。因為你迴圈的時候是從小到大迴圈找路徑的。
至此,零dp【i】 表示從i 頂點出發的最長路徑已經求出來了。那麼以i頂點結尾的最長路徑長度怎麼求呢?
可以想象只要把求解公式變一下就可以了dp[i] = max(dp[j] + g[j][i]);
求解順序變為拓撲排序
但是卻不能直接得到字典序求出。
上面討論的基礎上,我們來討論第二個問題,固定終點,求dag的最長路徑長度。假設終點為t,令dp【i】表示從i好頂點出發到達終點t能獲得的最長路徑長度。
那這與第乙個有什麼不同呢?
沒錯就是邊界,第一求得邊界是出度為0的點,dp值也為0,這個是求t點的dp值。
那麼dp【t】 = 0
那麼我們能不能還把其他的dp位置還設定為0呢?顯然不行,因為由於衝沒寫頂點出發可能無法到達終點t,如果dp還是初始化為0那麼就會得到錯誤的結果,我們應該初始化為-inf,如果是 +inf 會帶來麻煩的(因為我們求的最長路)求最短路反之。
然後我們需要設定乙個vis陣列,表示這個頂點是否訪問過
int dp(int i)
} return dp[i];
}
矩形巢狀問題:
最短路
動態規劃四(DAG最長路)
在圖的有關知識中已經了解了dag就是有向無環圖,其中計算最長路 關鍵路徑 的做法非常複雜,這裡介紹更簡單的方法。求整個dag的最長路徑 即不固定起點和終點 固定終點,求dag的最長路徑。給定乙個有向無環圖,怎樣求解整個圖的所有路徑中權值之和最大的那條。令dp i 表示從i號頂點出發能獲得的最長路徑長...
最短路 求最長最短路,求最短路的路徑
hdu 1595 find the longest of the shortest include include include include include include include include include include include include include defi...
最短路之 尋找每兩點之間最短路中的最長路
題目 hdu4460 題意 尋找每兩點之間最短路中的最長路。若存在某兩點不連通,就輸出 1.解答 對每個點spfa,然後找最長的邊。用鄰接鍊錶存 注意 雙向邊!include include include include include include includeusing namespace...