每次可以走2^k步求,最短路。实际上对于距离2^k的点连边就好,对于哪些点2^k,直接邻接矩阵快速幂就好
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
int n,m,a[55][55];
int f[55][55],tmp[55][55];
void work()
{
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
for (int l=1;l<=n;l++) if (tmp[j][i]&&tmp[i][l]) f[j][l]=1;
}
bool b[55];
int dis[55];
int ans()
{
queue<int> q;
q.push(1);
dis[1]=1;
while(!q.empty())
{
int u=q.front();q.pop();
for (int i=1;i<=n;i++) if (a[u][i]&&dis[i]==0)
{
dis[i]=dis[u]+1;
if (i==n) return dis[i]-1;
q.push(i);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
int u,v;
for (int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
tmp[u][v]=a[u][v]=1;
}
for (int i=1;i<=30;i++)
{
for (int x=1;x<=n;x++)
for (int y=1;y<=n;y++) f[x][y]=0;
work();
for (int x=1;x<=n;x++)
for (int y=1;y<=n;y++)
{
if (f[x][y]) a[x][y]=f[x][y];
tmp[x][y]=f[x][y];
}
}
printf("%d",ans());
return 0;
}