Luogu P1613 跑路 题解报告
【题目大意】
【思路分析】
我们设$g[i][j][k]$表示从$i$走$2^k$步能否到达$j$,$d[i][j]$表示$i$到$j$最少要走多少秒。
用倍增预处理出$g$,然后就可以$Floyd$跑最短路啦!QwQ
【代码实现】
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define g() getchar() 8 #define rg register 9 #define go(i,a,b) for(rg int i=a;i<=b;i++) 10 #define back(i,a,b) for(rg int i=a;i>=b;i--) 11 #define db double 12 #define ll long long 13 #define il inline 14 #define pf printf 15 #define mem(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 int fr(){ 18 int w=0,q=1; 19 char ch=g(); 20 while(ch<'0'||ch>'9'){ 21 if(ch=='-') q=-1; 22 ch=g(); 23 } 24 while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g(); 25 return w*q; 26 } 27 const int N=52; 28 int n,m,d[N][N]; 29 bool f[N][N][65]; 30 int main(){ 31 //freopen("","r",stdin); 32 //freopen("","w",stdout); 33 n=fr();m=fr();mem(d,0x3f); 34 go(i,1,m){ 35 rg int x=fr(),y=fr(); 36 d[x][y]=1;f[x][y][0]=1; 37 } 38 go(k,1,64) go(i,1,n) go(t,1,n) go(j,1,n)//注意循环嵌套的顺序 39 if(f[i][t][k-1]&&f[t][j][k-1]) f[i][j][k]=1,d[i][j]=1; 40 go(k,1,n) go(i,1,n) go(j,1,n) d[i][j]=min(d[i][j],d[i][k]+d[k][j]); 41 pf("%d\n",d[1][n]); 42 return 0; 43 }