1. 程式人生 > >倍增+Floyd最短路--luoguP1613 跑路

倍增+Floyd最短路--luoguP1613 跑路

傳送門 看到2k2^k就是妥妥的倍增qwqqwq,但是一開始的時候倍增陣列設成了g[i][j]g[i][j]表示從ii2j2^j步到的點,這樣的話是有問題的,因為之前走過的點可能會被覆蓋掉,在之後它就遺失了 所以要設g[i][j][k]g[i][j][k]表示從iijj走了2k2^k步是否可達 然後可以用floydfloyd最短路求一下從11nn的最短路就好了

#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; }