1. 程式人生 > >【洛谷P1613】跑路

【洛谷P1613】跑路

處理 spl mem include 維護 str splay opened ++

這道題說每一步可以走2k個距離,那麽這道題就直接和倍增建立了聯系。

由於n的範圍很小,我們可以用Floyd處理邊的關系,定義vis[i][j][k]表示ij之間是否存在2k的路徑,dis[i][j]表示ij之間的最短距離是多少。

我們可以先進行一次Floyd處理vis,枚舉ij以及中間點k,若vis[i][k][l-1]==1且vis[k][j][l-1]==1那麽有vis[i][j][l]=1且dis[i][j]=1.

我們在進行一次Floyd,維護dis即可,答案就是dis[1][n].

技術分享圖片
 1 #include <iostream>
 2 #include <cstdio>
 3
#include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 int n,m,dis[60][60],vis[60][60][70]; 8 int main() { 9 cin>>n>>m; 10 memset(dis,0x3f,sizeof(dis)); 11 memset(vis,0,sizeof(vis)); 12 // cout<<dis[1][n]; 13 for
(int i=1;i<=m;i++) { 14 int x,y; 15 cin>>x>>y; 16 vis[x][y][0]=1; 17 dis[x][y]=1; 18 } 19 for(int l=1;l<=64;l++) 20 for(int i=1;i<=n;i++) 21 for(int j=1;j<=n;j++) 22 for(int k=1;k<=n;k++) 23
if(vis[j][i][l-1]==1&&vis[i][k][l-1]==1) { 24 vis[j][k][l]=1; 25 dis[j][k]=1; 26 } 27 for(int k=1;k<=n;k++) 28 for(int i=1;i<=n;i++) 29 for(int j=1;j<=n;j++) 30 dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); 31 cout<<dis[1][n]<<endl; 32 return 0; 33 }
AC Code

【洛谷P1613】跑路