学floyd的时候竟然没去想,这次傻了,枚举中间点的循环得放在最前面
for(int t=1;t<=n;t++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],(dis[i][t]+dis[t][j]));
这道题用的是倍增+floyd
dp[i][j][k]表示i到j的距离为2的k次方
dis[i][j]表示从i到j最少转移的次数
#include <bits/stdc++.h>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>
#include <cstdlib>
#include<map>
using namespace std;
typedef long long ll;
const int inf=9999999;
const long long int mod=1e9+7;
int n,m,u,v;
int dis[55][55];
bool dp[55][55][64];
void work()
{
for(int t=0;t<64;t++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
if(dp[i][j][t]&&dp[j][k][t])
{
dp[i][k][t+1]=true;
dis[i][k]=1;
}
}
void floyd()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
dis[j][k]=min(dis[j][k],(dis[j][i]+dis[i][k]));
}
int main()
{
memset(dp,false,sizeof(dp));
for(int i=0;i<55;i++)
for(int j=0;j<55;j++)
dis[i][j]=inf;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
dp[u][v][0]=true;
dis[u][v]=1;
}
work();
floyd();
printf("%d",dis[1][n]);
return 0;
}