洛谷p1613 跑路

2021-10-09 16:42:14 字數 2049 閱讀 9389

大致題意:給一張有向圖(存在自環),每條邊權均為1,現在有一人要從1號結點走到n號結點,但是這個人有乙個神奇的瞬移機器,這個機器走2

k2^k

2k(k

kk為自然數)花費的時間都為1,問從起點到終點的最小花費時間。

思路如下:

step 1.我們可以處理出所有的從乙個點到達另乙個點的距離可以為2

k2^k

2k的路徑,並把這兩個點之間連一條權值為1的邊。

step 2.在我們新得到的圖上執行最短路演算法,求出從起點到達終點花費的最少時間。

下面我們來看看如何處理step 1:

狀態表示:用f[i

][j]

[k

]f[i][j][k]

f[i][j

][k]

記錄能否通過2

k2^k

2k的距離從i

ii到達jjj.

轉移方程:if(

f[i]

[u][

k−1]

if(f[i][u][k-1]

if(f[i

][u]

[k−1

]&&f[u

][j]

[k−1

])

f[u][j][k-1])

f[u][j

][k−

1]) 則f[i

][j]

[k

]f[i][j][k]

f[i][j

][k]

為真。需要注意:因為題意已經給出任意邊的邊權均為1,則可以用反證法證明:若f[i

][j]

[k

]f[i][j][k]

f[i][j

][k]

為真,則一定存在中間結點使得f[i

][u]

[k−1

]f[i][u][k-1]

f[i][u

][k−

1]&&f [u

][j]

[k−1

]f[u][j][k-1]

f[u][j

][k−

1]為真。

**如下:

#include

#include

using

namespace std;

const

int n =

100, m =

20000

;const

int k =35;

int f[n]

[n][k]

;int g[n]

[n];

int n,m;

intmain()

for(

int u=

1;u<=32;

++u)

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][u-1]

==1&&f[k]

[j][u-1]

==1)for

(int k=

1;k<=n;

++k)

for(

int i=

1;i<=n;

++i)

for(

int j=

1;j<=n;

++j)

g[i]

[j]=

min(g[i]

[k]+g[k]

[j],g[i]

[j]);

cout<[n]

}

洛谷 P1613 跑路

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

跑路 洛谷p1613

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

洛谷P1613 跑路

題目 倍增直接用圖論演算法必然解決不了這個問題,所以可以使用倍增演算法優化。我們遇到這個題該怎麼想,首先,題目要求的值是1到n的最小代價。代價是路徑的二進位制中1的個數。我們先預處理出每兩點之間是否有邊權和為 1 k 的路徑。這樣的話,代價預處理就可以只需考慮1的情況,因為每個數都可以由 1 處理之...