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...