洛谷1613 跑路 倍增 Floyd

2021-09-08 08:18:45 字數 1758 閱讀 4887

首先,我們一定要認識到本題中的最短時間所對應的道路不一定是在起點到終點的最短路。例如,起點到終點的最短路為 15

,那麼對 15

進行二進位制拆分的話是 11

11,這時求出的最短時間為4。然而如果有一條長度為 16

的路徑的話最短時間就為

1,顯然比之前求的更優 。

我們在這裡定義兩個陣列:in

td[i

][j]

,即代表點 (i

,j) 之間的最短跑步時間。bo

olg[

i][j

][k]

,它代表的是點 (i

,j) 之間是否有一條跑步時間為 2k

的一條道路。

我們對 g[

i][j

][k]

執行一遍 fl

oyd 來更新。

更新方程是:if

(g[i

][k]

[log

−1] && g[

k][j

][lo

g−1]

)g[i

][j]

[log

]=1 ,

d[i]

[j]=

1.顯然,我們處理完

g 陣列後所有可以在一秒之內到達的點對都已處理完畢。於是我們在圖上對 d[

i][j

] 再跑一遍 fl

oyd 即可。

時間複雜度為 o(

n3lo

gm)。

#include

#include

using namespace std;

const

int logn =60;

const

int maxm =

500000+5

;const

int maxn =60;

const

int inf =

100000000

;int d[maxn]

[maxn]

;bool g[maxn]

[maxn]

[logn]

;int

main()

for(

int p =

1; p < logn;

++p)

for(

int k =

1; k <= n;

++k)

for(

int i =

1; i <= n;

++i)

for(

int j =

1; j <= n;

++j)

for(

int k =

1;k <= n;

++k)

for(

int i =

1;i <= n;

++i)

for(

int j =

1;j <= n;

++j)

d[i]

[j]=

min(d[i]

[j], d[i]

[k]+ d[k]

[j])

;printf

("%d"

,d[1

][n]);

return0;

}

posted @

2018-10-08 17:23

em-lgh 閱讀(

...)

編輯收藏

倍增 Floyd 跑路 洛谷P1613

小a的工作不僅繁瑣,更有苛刻的規定,要求小a每天早上在6 00之前到達公司,否則這個月工資清零。可是小a偏偏又有賴床的壞毛病。於是為了保住自己的工資,小a買了乙個十分牛b的空間跑路器,每秒鐘可以跑2 k千公尺 k是任意自然數 當然,這個機器是用longint存的,所以總跑路長度不能超過maxlong...

洛谷 P1613 跑路 倍增 Floyd

題目描述 小a的工作不僅繁瑣,更有苛刻的規定,要求小a每天早上在6 00之前到達公司,否則這個月工資清零。可是小a偏偏又有賴床的壞毛病。於是為了保住自己的工資,小a買了乙個十分牛b的空間跑路器,每秒鐘可以跑2 k千公尺 k是任意自然數 當然,這個機器是用longint存的,所以總跑路長度不能超過ma...

洛谷1613跑路(倍增)

題目描述 description 小a的工作不僅繁瑣,更有苛刻的規定,要求小a每天早上在6 00之前到達公司,否則這個月工資清零。可是小a偏偏又有賴床的壞毛病。於是為了保住自己的工資,小a買了乙個十分牛b的空間跑路器,每秒鐘可以跑2 k千公尺 k是任意數 當然,這個機器是用longint存的,所以總...