题意
思考
跑最短路再判定肯定是错的,我们可以这样做:用 (f[i][j][k]) 表示 (i) 是否能用 (2^k) 步到达 (j),能到达为 (1), 不能到达为 (0), 跑一遍(floyd)来传递,将能用 (2^k) 步到达的两点间边权设为 (1),最后跑一遍最短路即可
代码
#include<bits/stdc++.h>
using namespace std;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x * f;
}
const int N = 110;
int mp[N][N], f[N][N][N], n, m;
void init(){
for(int p=1; p<=64; p++){
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][p-1] && f[k][j][p-1]){
f[i][j][p] = 1; mp[i][j] = 1;
}
}
}
}
}
for(int k=1; k<=n; k++){
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
if(mp[i][k] + mp[k][j] < mp[i][j]){
mp[i][j] = mp[i][k] + mp[k][j];
}
}
}
}
}
int main(){
n = read(), m = read();
memset(mp, 0x3f, sizeof(mp));
for(int i=1; i<=m; i++){
int u = read(), v = read();
mp[u][v] = 1; f[u][v][0] = 1;
}
init();
cout << mp[1][n];
return 0;
}