floyed最短路 矩陣乘法優化 relays

2021-09-27 00:26:36 字數 2186 閱讀 6095

fj的n(2 <= n <= 1,000,000)頭奶牛選擇了接力跑作為她們的日常鍛鍊專案。至於進行接力跑的地點,自然是在牧場中現有的t(2 <= t <= 100)條跑道上。

農場上的跑道有一些交匯點,每條跑道都鏈結了兩個不同的交匯點i1_i和i2_i(1 <= i1_i <= 1,000; 1 <= i2_i <= 1,000)。每個交匯點都是至少兩條跑道的端點。奶牛們知道每條跑道的長度length_i(1 <= length_i <= 1,000),以及每條跑道鏈結的交匯點的編號。並且,沒有哪兩個交匯點由兩條不同的跑道直 接相連。你可以認為這些交匯點和跑道構成了一張圖。

為了完成一場接力跑,所有n頭奶牛在跑步開始之前都要站在某個交匯點上(有些交匯點上可能站著不只1頭奶牛)。當然,她們的站位要保證她們能夠將接力棒順次傳遞,並且最後持棒的奶牛要停在預設的終點。

你的任務是,寫乙個程式,計算在接力跑的起點(s)和終點(e)確定的情況下,奶牛們跑步路徑可能的最小總長度。顯然,這條路徑必須恰好經過n條跑道。

我們可以設f[i

][j]

[t]f[i][j][t]

f[i][j

][t]

表示i到j的最短路徑中,經過t

tt條跑道的最短路徑。

那麼類似floyed的迭代方式,我們可以得到:f[i

][j]

[t]=

min⁡(f

[i][

k][t

−1]+

f[k]

[j][

t−1]

)f[i][j][t]=\min(f[i][k][t-1]+f[k][j][t-1])

f[i][j

][t]

=min(f

[i][

k][t

−1]+

f[k]

[j][

t−1]

)我們考慮如何優化這乙個方程,我們發現:f[i

][j]

=∑f[

i][k

]∗f[

k][j

]f[i][j]=\sum f[i][k]*f[k][j]

f[i][j

]=∑f

[i][

k]∗f

[k][

j]就是乙個矩陣乘法的形式。

那麼類似的,我們可以得到乙個廣義的矩陣乘法形式: f[i

][j]

=min⁡(

f[i]

[k]+

f[k]

[j])

f[i][j]=\min(f[i][k]+f[k][j])

f[i][j

]=min(f[

i][k

]+f[

k][j

])實現方式就像這樣:

那麼我們只需要做t

tt次矩陣乘法即可。

由於t比較大,我們需要考慮用矩陣快速冪來實現。

#include

#include

#include

#include

using

namespace std;

const

int n =

500;

int n, m, s, t, p =0;

int a[n]

[n], b[n]

[n];

map <

int,

int> map;

intread

(void

)void

mul(

int a[

500]

[500],

int b[

500]

[500])

void

mulself

(int a[

500]

[500])

intmain

(void

)memcpy

(b,a,

sizeof a)

; n --

;while

(n >0)

printf

("%d\n"

, b[map[s]

][map[t]])

;return0;

}

Floyed 廉價最短路徑

乙個圖中,在滿足最短路的前提下,求最小代價 圖是由一組頂點和一組邊組成的。一條邊連線兩個頂點。例如,圖1表示了乙個有4個頂點v 5條邊的圖。圖中,每條邊e是有方向的,方向從起點到終點,並且每條邊都有價值。用整數0,1,m 1可以表示乙個有m個頂點的圖。一條路徑連線了乙個點vi和另乙個點vj,其方向與...

最短路徑與Floyed演算法

乙個矩陣cost n n cost i j 表示從i到j的路徑長度,如果不通的話就是 1 現在給你乙個矩陣,希望查詢出從p到q的最短路徑長度,不存在路的話輸出 no 是的,這是乙個最短路徑問題,用單源最短路徑 dijkstra 和多源最短路徑 floyd 演算法都可以實現,時間要取決於n和q,因為單...

最短路上的統計 Floyed

description 乙個無向圖上,沒有自環,所有邊的權值均為1,對於乙個點對 a,b 我們要把所有a與b之間所有最短路上的點的總個數輸出。input 第一行n,m,表示n個點,m條邊 接下來m行,每行兩個數a,b,表示a,b之間有條邊 在下來乙個數p,表示問題的個數 接下來p行,每行兩個數a,b...