传送门
看到
2
k
2^k
2k就是妥妥的倍增
q
w
q
qwq
qwq,但是一开始的时候倍增数组设成了
g
[
i
]
[
j
]
g[i][j]
g[i][j]表示从
i
i
i走
2
j
2^j
2j步到的点,这样的话是有问题的,因为之前走过的点可能会被覆盖掉,在之后它就遗失了
所以要设
g
[
i
]
[
j
]
[
k
]
g[i][j][k]
g[i][j][k]表示从
i
i
i到
j
j
j走了
2
k
2^k
2k步是否可达
然后可以用
f
l
o
y
d
floyd
floyd最短路求一下从
1
1
1到
n
n
n的最短路就好了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define N 55
#define M 10005
using namespace std;
int n,m,a[N][N],f[N][N],g[N][N][65];
queue<int> q;
inline int rd(){
int x=0,f=1;char c=' ';
while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
int main(){
n=rd(); m=rd(); memset(f,0x3f,sizeof f);
for(int i=1;i<=m;i++){
int x=rd(),y=rd();
a[x][y]=1; g[x][y][0]=1; f[x][y]=1;
}
for(int t=1;t<63;t++)
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(g[i][k][t-1] && g[k][j][t-1]){
g[i][j][t]=1; f[i][j]=1;
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
printf("%d\n",f[1][n]);
return 0;
}