洛谷 1613 跑路 倍增

2021-10-24 08:34:45 字數 2415 閱讀 7811

題目描述

小a的工作不僅繁瑣,更有苛刻的規定,要求小a每天早上在6:00

6:00

6:00

之前到達公司,否則這個月工資清零。可是小a偏偏又有賴床的壞毛病。於是為了保住自己的工資,小a買了乙個十分牛b的空間跑路器,每秒鐘可以跑2

k2^k

2k千公尺(k是任意自然數)。當然,這個機器是用lon

gint

longint

longin

t存的,所以總跑路長度不能超過max

long

in

tmaxlongint

maxlon

gint

千公尺。小a的家到公司的路可以看做乙個有向圖,小a家為點1

11,公司為點n,每條邊長度均為一千公尺。小a想每天能醒地盡量晚,所以讓你幫他算算,他最少需要幾秒才能到公司。資料保證1到n至少有一條路徑。

輸入格式

第一行兩個整數n,m

n,mn,

m,表示點的個數和邊的個數。

接下來m行每行兩個數字u,v

u,vu,

v,表示一條u到v的邊。

輸出格式

一行乙個數字,表示到公司的最少秒數。

輸入輸出樣例

輸入 #1複製

4 41 1

1 22 3

3 4輸出 #1複製

1說明/提示

【樣例解釋】

1

−>1−

>2−

>3−

>

41->1->2->3->4

1−>1−

>2−

>3−

>

4,總路徑長度為4

44千公尺,直接使用一次跑路器即可。

【資料範圍】

50

5050

%的資料滿足最優解路徑長度<

=1000

<=1000

<=1

000;

100

10010

0%的資料滿足n

<=50

,m

<

=10000

n<=50,m<=10000

n<=5

0,m<=1

0000

,最優解路徑長<=m

axlo

ngin

t<=maxlongint

<=m

axlo

ngin

t。解題思路

題目已經比較明顯的標出了主要演算法:倍增

對於任意兩點,只要他們之間距離等於2

k2^k

2k,就可以用1的時間相互到達。所以我們可以先將這些距離能為2

k2^k

2k的點對用邊權為1的邊連上。

考慮n

<=50

n<=50

n<=5

0,可以直接flo

ye

dfloyed

floyed

,用f lo

ye

dfloyed

floyed

做一次最短路徑,就可以求出答案了。

**

#include.h>

using namespace std;

long long m,n,u,v,k,dis[60]

[60];

bool f[60]

[60][

70];int main()

for(int s=

1;s<=

64;s++

)for

(int k=

1;k<=n;k++

)for

(int i=

1;i<=n;i++

)for

(int j=

1;j<=n;j++)if

(f[i]

[k][s-1]

==1&&f[k]

[j][s-1]

==1)for

(int k=

1;k<=n;k++

)for

(int i=

1;i<=n;i++

)for

(int j=

1;j<=n;j++)if

(i!=j&&j!=k&i!=k&&dis[i]

[j]>dis[i]

[k]+dis[k]

[j])

printf

("%d"

,dis[1]

[n])

;}

洛谷1613跑路(倍增)

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

洛谷1613 跑路 倍增 Floyd

首先,我們一定要認識到本題中的最短時間所對應的道路不一定是在起點到終點的最短路。例如,起點到終點的最短路為 15 那麼對 15 進行二進位制拆分的話是 11 11,這時求出的最短時間為4。然而如果有一條長度為 16 的路徑的話最短時間就為 1,顯然比之前求的更優 我們在這裡定義兩個陣列 in td ...

洛谷1613 跑路(倍增 最短路)

點此看題面 大致題意 小a aa要從1 11號節點到n nn號節點,已知他每個單位時間可以跑2 k2 k 2k千公尺,求他最少需要多少個單位時間。預處理由於資料範圍較小,我們可以先大力預處理。首先,將題目中給出的邊邊權初始化為000。若從一點出發,到兩點皆有一條邊權為k kk的邊,就將這兩點之間連一...