總結 最短路徑數問題

2022-05-02 03:00:10 字數 1109 閱讀 4907

problem:給定一張n個點m條邊的帶權有向圖,從起點s出發到達終點e,有多少種方法可以走最短的路徑到達終點e?

solution:

首先我們得找到s到各點的單源最短路值(spfa/dijkstra)。

問題一,如何確定某個點k是否在s到v的最短路上。這只需要乙個判斷語句:dist[s][k]+dist[k][v]==dist[s][v]。

問題二,如何從v點出發走最短路徑走到點s?找邊集(v,k)使得dist[s][k]+edge[k][v]==dist[s][v]。到達點k後,我們再沿k到s的最短路走即可。為什麼不是dist[s][k]+dist[k][v]==dist[s][v]?因為若是dist[k][v],k到v的最短路徑上可能並非單邊,而是多條邊和多個點。

知道這些後,我們可以使用搜尋遍歷每條s到v的最短路(從v出發),然後統計路徑的條數加起來。然而這個路徑數可能很大,這樣子的話就會超時。

那麼我們不妨使用記憶化搜尋。這樣的話這個問題轉換成了乙個dp方程。

狀態:f[i][j] 從i到j的最短路條數值

轉移:f[i][j]=sum ( (k,j)屬於e , d[i][k]+e[k][j]==d[i][j] )

邊界:f[i][i]=1

問題得到解決。

然而這玩意會不會有更好的解決方法?到底究竟要不要使用遞迴?有,可以不用遞迴。

當我們跑了一邊spfa之後,以s為源,整張圖會轉換成乙個最短路圖。點u能向點v連一條有向邊的條件為dist[u]+e[u][v]==dist[v]。整張圖應該轉成了一張dag(邊權為正)。

那麼s到乙個點k的最短路,也就是f[k],應該從sum ( (j,k)屬於e )轉換過來,也就是每個出邊指向k的點的路徑數之和。而若想求得k,每個j都應該求得。

是不是感覺很熟悉?想要求得乙個點的資訊,必須將所有指向它的點的資訊全部求得。這讓我們想起了拓撲排序。我們可以使用拓撲排序的順序對每個點進行處理,由此可以使用非遞迴求得s到每個點的路徑數。

一開始,入度為0的點,也就是點s,顯然其f[s]=1.

本質還是dp的過程。

最短路 最短路徑問題

題目描述 平面上有n個點 n 100 每個點的座標均在 10000 10000之間。其中的一些點之間有連線。若有連線,則表示可從乙個點到達另乙個點,即兩點間有通路,通路的距離為兩點直線的距離。現在的任務是找出從一點到另一點之間的最短路徑。input 共有n m 3行,其中 第一行為乙個整數n。第2行...

XJOJ 路徑數 最短路 最短路路徑數量

題目大意 euphemia到乙個n n的藥草田裡採藥,她從左上角的格仔田 第一行,第一列 出發,要到達右下角 第n行,第n列 的格仔田,每次她可以走到與當前格仔有邊相鄰的格仔去,但她不會走已經走過的格仔,而且出於對美的要求,她走過的路徑是關於 左下 右上 對角線對稱的。由於地勢不同,在每個格仔田採藥...

Codeup最短路徑 最短路徑問題

給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。輸入n,m,點的編號是1 n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費為p。最後一行是兩個數 s,t 起點s,...