這題因為道路的長度都是大於 ,所以其實 就只是與 之間有直達道路的所有城市中最近的那個城市。
知道圖會是一棵樹後就會知道這題不能用單純的最短路通過,我們可以知道樹上最短路會唯一,因此假設我們要找 的最短路徑的話可以先找出 到根節點以及 到根節點的距離相加,最後再扣掉 就會是答案,扣兩次的原因是因為 到根節點這段被重複算到兩次,它並不會被包含在最短路裡,因此需要扣掉,距離計算的部分則是可以在 dfs 時同步完成。
本題只想要測試各位的 dfs 能力,以及三角形棋盤的聯通性。
唯一需要注意的就是「每個 row 的邊界都不一樣大」
本題賽後加強測資,不影響賽中 Submission。
看到值域可以很明顯的知道從每個點做一次最短路徑是行不通的,
不如我們換個想法,一個點到最近的維修站距離,
也可以視為從所有的維修站同時出發,
看哪個維修站先走到這個點,即為該點到最近維修站的距離。
那麼我們就同時從所有維修站出發,也就是做多個起點的最短路徑,
但是做 次最短路又太耗費時間,因此可以採用一個方法,
我們使用一個「超級起點」,
且將超級起點連到所有的維修站,距離為 ,
則只要做一次從超級起點出發的最短路徑,
可以直接使用 dijkstra 演算法求解。
目標是要找出總權重最小的連通生成子圖
連通的生成子圖就是題目要求的地圖
首先,子圖中並沒有任何的邊,可以看做子圖有 個連通塊
一個目標要將這 個連通塊通通相連,使得只剩 個連通塊
接著將 權重的邊都放入子圖中,這樣不會增加總權重,且連通塊數量會變少
最後剩下的連通塊,只能透過 權重的邊相連。這樣產生了總權重最小的連通圖
實作上,枚舉所有還未被 DFS 拜訪過的點
對於每一點將它能透過 權重路徑到達的點都納入連通塊中
這部分透過 DFS,將 權重邊拜訪到的鄰點,一層層加入到連通塊中
當無法繼續進行 DFS,表示該連通塊已生成完畢
接著對於剩下的點進行一樣的操作。
同解法 1,可改成使用 BFS 進行點的拜訪