倍增+Floyd最短路--luoguP1613 跑路
阿新 • • 發佈:2018-12-15
傳送門 看到就是妥妥的倍增,但是一開始的時候倍增陣列設成了表示從走步到的點,這樣的話是有問題的,因為之前走過的點可能會被覆蓋掉,在之後它就遺失了 所以要設表示從到走了步是否可達 然後可以用最短路求一下從到的最短路就好了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include <cstring>
#include<cmath>
#include<queue>
#define N 55
#define M 10005
using namespace std;
int n,m,a[N][N],f[N][N],g[N][N][65];
queue<int> q;
inline int rd(){
int x=0,f=1;char c=' ';
while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
while(c<='9' && c>='0') x= x*10+c-'0',c=getchar();
return x*f;
}
int main(){
n=rd(); m=rd(); memset(f,0x3f,sizeof f);
for(int i=1;i<=m;i++){
int x=rd(),y=rd();
a[x][y]=1; g[x][y][0]=1; f[x][y]=1;
}
for(int t=1;t<63;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++)
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\n",f[1][n]);
return 0;
}