給定乙個有向圖,起點為\(1\),終點為\(n\),所有邊的長度都為\(1\).現在要從起點走到終點,每次走\(2^k\)的代價是\(1\).(這個\(k\)是任意的,但\(2^k\)不能超過\(longint\)範圍).求最小代價.
最開始的想法:把距離為\(2^k\)的兩個點連邊,然後$ dijkstra \(跑最短路.要處理出倍增陣列\)f[i][k]\(表示從\)i$出發走\(2^k\)步到的點.發現,其實這樣的點是不確定的,因為有環.
雖然並不能確定乙個點走\(2^k\)步能到達的點,但是可以通過\(floyed\)確定兩個點\(i,j\)能不能走\(2^k\)到達.感覺這裡有點像乙個傳遞閉包.
\(f[k][i][j]\)表示\(i\)走\(2^k\)步能不能到達\(j\).
\(f[k][i][j]|=f[k-1][i][p]\&f[k-1][p][j]\).
這樣就可以確定連邊情況.然而\(n\)這麼小,直接矩陣存下來跑\(floyed\)就好了,何必寫鏈式前向星再跑\(dijkstra\)呢.
#include#define il inline
#define ri register int
#define go(i,a,b) for(ri i=a;i<=b;++i)
#define yes(i,a,b) for(ri i=a;i>=b;--i)
#define e(i,u) for(ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
while(c>='0'&&c<='9')
return x*y;
}const int n=60;
int n,m;ll f[70][n][n],a[n][n];
int main()
go(k,1,64)
go(p,1,n)
go(i,1,n)
go(j,1,n)
go(i,1,n)a[i][i]=0;
go(p,1,n)
go(i,1,n)
go(j,1,n)
a[i][j]=min(a[i][j],a[i][p]+a[p][j]);
printf("%lld\n",a[1][n]);
return 0;
}
洛谷1613跑路
題目描述 小a的工作不僅繁瑣,更有苛刻的規定,要求小a每天早上在6 00之前到達公司,否則這個月工資清零。可是小a偏偏又有賴床的壞毛病。於是為了保住自己的工資,小a買了乙個十分牛b的空間跑路器,每秒鐘可以跑2 k千公尺 k是任意自然數 當然,這個機器是用longint存的,所以總跑路長度不能超過ma...
洛谷 1613 跑路
題目描述 小a的工作不僅繁瑣,更有苛刻的規定,要求小a每天早上在6 00之前到達公司,否則這個月工資清零。可是小a偏偏又有賴床的壞毛病。於是為了保住自己的工資,小a買了乙個十分牛b的空間跑路器,每秒鐘可以跑2 k千公尺 k是任意自然數 當然,這個機器是用longint存的,所以總跑路長度不能超過ma...
跑路(洛谷 1613)
小a的工作不僅繁瑣,更有苛刻的規定,要求小a每天早上在6 00之前到達公司,否則這個月工資清零。可是小a偏偏又有賴床的壞毛病。於是為了保住自己的工資,小a買了乙個十分牛b的空間跑路器,每秒鐘可以跑2 k千公尺 k是任意自然數 當然,這個機器是用longint存的,所以總跑路長度不能超過maxlong...