洛谷 P1613 跑路 (倍增)
阿新 • • 發佈:2019-01-12
學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; }