倍增+Floyd
首先令$g[i][j][k]$表示$i$到$j$的有没有长度为$2^{k}$的路径,1表示有,0表示没有
那么可以处理出有之间连边($u$->$v$)的两点$u$,$v$,$g[u][v][0]=1$
然后再令$f[i][j]$表示i到j经过$2^{k}$的边的个数
那么只要存在一个$k$,使得$g[i][j][k]==1$那么$f[i][j]=1$
然后以$f$数组跑Floyd处理出1-n的最短路即可
#include <bits/stdc++.h> #define inf 1e9 using namespace std; int n,m,g[60][60][65]; int f[60][60]; int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) f[i][j]=inf; } for (int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); g[u][v][0]=1;//同上 f[u][v]=1; } for (int t=1;t<=64;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++)//Floyd { 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 ",f[1][n]); }