因为每一次只能走2的k次方步,所以我们先处理除 那些点之间可以直接通过走一次(即长度为2的k次方)能走到,实现嘛,有点类似Floyd跑传递闭包维护可达性,然后再随随便便跑一个最短路数据这么小floyd泡一泡就好了,唯一的坑点就是,我靠居然是有向图
#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 10020
#define LL long long
using namespace std;
LL n,m,g[55][55],mat[70][55][55];
int main(){
scanf("%lld%lld",&n,&m);
for(LL i=1;i<=n;i++)
for(LL j=1;j<=n;j++)g[i][j]=1e17;
for(LL a,b,i=1;i<=m;i++){
scanf("%lld%lld",&a,&b);
mat[0][a][b]=1;
g[a][b]=1;
}
for(LL p=1;p<=64;p++)
for(LL i=1;i<=n;i++)
for(LL j=1;j<=n;j++)
for(LL k=1;k<=n;k++)
if(mat[p-1][i][k]&&mat[p-1][k][j]){
mat[p][i][j]=1;
g[i][j]=1;
}
for(LL k=1;k<=n;k++){
for(LL i=1;i<=n;i++){
for(LL j=1;j<=n;j++){
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
}
}
printf("%lld",g[1][n]);
return 0;
}