zoukankan      html  css  js  c++  java
  • luogu P1613 跑路

    P1613 跑路

    2017-09-17


    题目描述

    小A的工作不仅繁琐,更有苛刻的规定,要求小A每天早上在6:00之前到达公司,否则这个月工资清零。可是小A偏偏又有赖床的坏毛病。于是为了保住自己的工资,小A买了一个十分牛B的空间跑路器,每秒钟可以跑2^k千米(k是任意自然数)。当然,这个机器是用longint存的,所以总跑路长度不能超过maxlongint千米。小A的家到公司的路可以看做一个有向图,小A家为点1,公司为点n,每条边长度均为一千米。小A想每天能醒地尽量晚,所以让你帮他算算,他最少需要几秒才能到公司。数据保证1到n至少有一条路径。


    输入输出格式

    输入格式:

    第一行两个整数n,m,表示点的个数和边的个数。

    接下来m行每行两个数字u,v,表示一条u到v的边。

    输出格式:

    一行一个数字,表示到公司的最少秒数。


    输入输出样例

    输入样例#1:
    4 4
    1 1
    1 2
    2 3
    3 4
    
    输出样例#1:
    1

    说明

    【样例解释】

    1->1->2->3->4,总路径长度为4千米,直接使用一次跑路器即可。

    【数据范围】

    50%的数据满足最优解路径长度<=1000;

    100%的数据满足n<=50,m<=10000,最优解路径长度<=maxlongint。


     预处理处所有能1s到的,然后跑最短路....hhh 

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    const int INT=(int)1e9+7;
    int read(){
        char ch=getchar();
        int an=0,f=1;
        while(!('0'<=ch&&ch<='9')){if(ch=='-');ch=getchar();}
        while('0'<=ch&&ch<='9'){an=an*10+ch-'0';ch=getchar();}
        return an*f;
    }
    int V[100][100],n,m;
    bool f[100][100][50];
    void spell_floyd(){
        for(int k=1;k<=30;k++)
            for(int l=1;l<=n;l++)
                for(int i=1;i<=n;i++)
                    for(int j=1;j<=n;j++)            
        {
            f[i][j][k]=f[i][j][k]||(f[i][l][k-1]&&f[l][j][k-1]);
            if(f[i][j][k])V[i][j]=1;
        }
    }
    void floyd(){
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    V[i][j]=min(V[i][j],V[i][k]+V[k][j]);
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        V[i][j]=INT;
        for(int i=1;i<=m;i++){
            int x,y;
            x=read();y=read();
            f[x][y][0]=1;
            V[x][y]=1;
        }
        spell_floyd();
        floyd();
        cout<<V[1][n];
        return 0;
    }
    qwq

    首先这个跑路器是能用好几次的,不要和某个s一样以为只能用一次

    也就是说,所有2k的距离都是可以一秒到达的

    于是就可以用到倍增的思想

    倍增预处理出所有满足距离是2k(即一秒可达)的i,j

    然后跑floyd即可

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=100;
    int n,m;
    int f[40][N][N],g[N][N];
    void multy()
    {
         for(int z=1;z<=32;++z)
         for(int k=1;k<=n;++k)
         for(int i=1;i<=n;++i)
         for(int j=1;j<=n;++j)
         if(f[z-1][i][k]&&f[z-1][k][j])
         {
           f[z][i][j]=1;
           g[i][j]=1;
         }
    }
    void floyd()
    {
         for(int k=1;k<=n;++k)
         for(int i=1;i<=n;++i)
         for(int j=1;j<=n;++j)
         g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
        g[i][j]=int(1e7);
        for(int i=1;i<=m;++i)
        {
          int x,y;
          scanf("%d%d",&x,&y);
          f[0][x][y]=1;
          g[x][y]=1;
        }
        multy();
        floyd();
        cout<<g[1][n]<<endl;
        return 0;
    }
    跑路

    s:江南皮革厂老板跑路了 

    w:原价二百的跑路器现在只要两千

  • 相关阅读:
    Qt计算器开发(三):执行效果及项目总结
    [HNOI2019]校园旅行
    How to fix nuget Unrecognized license type MIT when pack
    How to fix nuget Unrecognized license type MIT when pack
    git 通过 SublimeMerge 处理冲突
    git 通过 SublimeMerge 处理冲突
    git 上传当前分支
    git 上传当前分支
    gif 格式
    gif 格式
  • 原文地址:https://www.cnblogs.com/ck666/p/7532922.html
Copyright © 2011-2022 走看看