最短路徑 披著最短路徑外衣的最小生成樹

2021-09-24 21:01:46 字數 1232 閱讀 6189

注意到第k條路徑的長度為2^k,則第k條路徑的長度會大於前k-1條路徑的

總和。由此我們可知兩個推斷:

(1)在新增第k條路徑時,如果路徑k連線的兩個城市a 、b已經通過其他路徑間接的連通了,那麼第k條路徑絕對不是ab間的最短路徑(第k條路徑之後的路徑也不可能有比當前ab路徑更短的路徑了,因為第k條路徑的長度會大於前k-1條路徑的總和)

(2)在新增第k條路徑時,如果路徑k連線的兩個城市a 、b是第一次被連通了(也就是說此前沒有任何路徑能連通ab,包括通過多條路徑間接連通),那麼路徑k就是ab之間的最短距離了,因為以後不可能存在更短的路徑連線ab,以後的單條路徑只會越來越長。

通過上述的推斷,我們可以利通過建立乙個最小連通樹的同時算出0號城市到各個城市的最小路徑。

具體的演算法:

(1)構造乙個並查集,每個城市指向自己,二維陣列d記錄城市之間的距離,初始化為-1不可達,d[i][i]初始化為0

(2)取第一條路徑,第一條路徑連線了城市a、b,城市a、b間最短路徑就是第一條路徑,然後把a、b合併在乙個集合裡

(3)再取一條路徑,

(一)如果這條邊連線的城市c、d,已經在同乙個集合裡了(即已經聯通了),那麼當前的路徑一定不是cd之間的最短路徑了,忽略之(理由是推斷(1)),繼續看下一條路徑。

(二)如果這條路徑連線的城市c、d不在同乙個集合裡(之前沒有聯通過),很好,這條路徑是cd之間的最短路徑(理由是推斷(2));除此之外我們還可以看看通過這條路徑能不能讓c集合裡的城市到d集合裡的城市之間的路徑更短呢?即是不是d[i][j]>(d[i][c]+dist+d[d][j]) ?(注意i和c乙個集合,d和j乙個集合),如果是的話可以更新一下這個值。

(4)重複(3)直到所有路徑都處理過了

0號城市到各個城市i的最小路徑結果就是d[0][i]了

#include#define n 100

int dis[n][n];

int father[n];

int findroot(int x)

}int mod(int x,int y)

return ret;

}int main(){

int n,m;

while(scanf("%d%d",&n,&m)!=eof){

int i,j,k,a,b,x,y,dist;

for(i=0;i

Codeup最短路徑 最短路徑

n個城市,標號從0到n 1,m條道路,第k條道路 k從0開始 的長度為2 k,求編號為0的城市到其他城市的最短距離。第一行兩個正整數n 2 n 100 m m 500 表示有n個城市,m條道路,接下來m行兩個整數,表示相連的兩個城市的編號。n 1行,表示0號城市到其他城市的最短路,如果無法到達,輸出...

Codeup最短路徑 最短路徑問題

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

最短路徑之最短路徑問題

提交 狀態 討論版 命題人 外部匯入 題目描述 平面上有n個點 n 100 每個點的座標均在 10000 10000之間。其中的一些點之間有連線。若有連線,則表示可從乙個點到達另乙個點,即兩點間有通路,通路的距離為兩點間的直線距離。現在的 任務是找出從一點到另一點之間的最短路徑。輸入共n m 3行,...