天天看點

POJ 3463 Sightseeing (Dijkstra 次短路)

題目大意:求出圖中最短路的條數+比最短路長度大1的路條數。

好題,需要比較深刻地了解Dijkstra的思想。

如果直接求比最短路大1的路,不太好把它轉化成一個階段性、符合最優子結構的模型,求解起來可能會比較麻煩。

是以我們直接求次短路的條數,然後判斷下次短路是不是比最短路大1即可。

二維Dijkstra求次短路(k很小時的k短路也适用):

我們知道Dijkstra就是不斷地用已經确定最短路的節點(黑色)去松弛未确定的點(白色),用數學歸納法很容易證明這是正确的。它的核心思想就是某個節點的最短路一定是由它前驅節點的最短路擴充來的。那麼對于次短路也可以類似的看:一個節點的次短路一定是由它前驅節點的最短路 or 次短路擴充而來的。那麼我們就可以把節點分成兩層處理:一層處理、存儲最短路,另一層處理、存儲次短路。這樣, 用于記錄狀态的數組變成了二維, 放進堆中的狀态也必須是"二維"的, 這裡的"二維"并不是要你開個二維數組, 而是需要在放入堆中的結構體裡多加一個标記變量, 用于辨別到底是最短路還是次短路, 當然, 用于标記已經确定最短路、次短路的點的closed表同樣要變成二維的。循環結束條件是堆為空, 因為要計數, 就必須周遊所有情況.

具體在做狀态轉移的時候, 拿到目前狀态, 擴充下一狀态, 設目前狀态長度為d, 下一狀态最短路和次短路狀态分别是d0和d1, 則:

d小于d0, 則d1=d0,d0=d, 計數都重置為所賦的值對應的計數.

d等于d0, 則累加最短路計數.

d小于d1, 則d1=d, 重置次短路計數為所賦的值對應的計數.

d等于d1, 則累加次短路計數.

舉杯獨醉,飲罷飛雪,茫然又一年歲。 ------AbandonZHANG