首页 > 其他 > 详细

P1613 跑路

时间:2018-10-26 10:23:18      阅读:179      评论:0      收藏:0      [点我收藏+]

传送门

设 f [ i ] [ j ] [ k ] 为表示从 i 到 j 是否有一条 $2^k$ 长度的路径

那么像 Floyd 一样枚举中转点,起点,终点转移就好了:

if (f [ a ] [ b ] [ k-1 ] && f [ b ] [ c ] [ k-1 ] )   f [ a ] [ c ] [ k ] = 1

设 dis [ i ] [ j ] 表示 i 到 j 的距离,初始如果 i 到 j 有长度为 $2^k$ 的路径 dis [ i ] [ j ] =1

然后跑 Floyd 更新 dis,最后输出 dis [ 1 ] [ n ]

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9) { if(ch==-) f=-1; ch=getchar(); }
    while(ch>=0&&ch<=9) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=65;
int n,m;
int dis[N][N];
bool f[N][N][N];
inline void pre()//预处理f
{
    for(int i=1;i<N;i++)//枚举长度2^i
        for(int k=1;k<=n;k++)//枚举中转点
            for(int u=1;u<=n;u++)//枚举起点
                for(int v=1;v<=n;v++)/*枚举终点*/ if(f[u][k][i-1]&&f[k][v][i-1]) f[u][v][i]=dis[u][v]=1;
}
int main()
{
    memset(dis,0x3f,sizeof(dis));//初始化
    int a,b;
    n=read(); m=read();
    for(int i=1;i<=m;i++) a=read(),b=read(),f[a][b][0]=dis[a][b]=1;
    pre();
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);//跑Floyd
    printf("%d",dis[1][n]);
    return 0;
}

 

P1613 跑路

原文:https://www.cnblogs.com/LLTYYC/p/9854542.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!