• 洛谷$1613$ 跑路


    (Des)

    给定一个有向图,起点为(1),终点为(n),所有边的长度都为(1).现在要从起点走到终点,每次走(2^k)的代价是(1).(这个(k)是任意的,但(2^k)不能超过(longint)范围).求最小代价.

    (Sol)

    最开始的想法:把距离为(2^k)的两个点连边,然后$ Dijkstra (跑最短路.要处理出倍增数组)f[i][k](表示从)i$出发走(2^k)步到的点.发现,其实这样的点是不确定的,因为有环.

    虽然并不能确定一个点走(2^k)步能到达的点,但是可以通过(Floyed)确定两个点(i,j)能不能走(2^k)到达.感觉这里有点像一个传递闭包.

    (f[k][i][j])表示(i)(2^k)步能不能到达(j).

    (f[k][i][j]|=f[k-1][i][p]&f[k-1][p][j]).

    这样就可以确定连边情况.然而(n)这么小,直接矩阵存下来跑(Floyed)就好了,何必写链式前向星再跑(Dijkstra)呢.

    (Code)

    #include<bits/stdc++.h>
    #define il inline
    #define Ri register int
    #define go(i,a,b) for(Ri i=a;i<=b;++i)
    #define yes(i,a,b) for(Ri i=a;i>=b;--i)
    #define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define db double
    #define inf 2147483647
    using namespace std;
    il int read()
    {
        Ri x=0,y=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        return x*y;
    }
    const int N=60;
    int n,m;ll f[70][N][N],a[N][N];
    int main()
    {
        n=read(),m=read();
        go(i,1,n)go(j,1,n)a[i][j]=inf;
        go(i,1,m)
        {
    	Ri u=read(),v=read();
    	f[0][u][v]=1;a[u][v]=1;
        }
        go(k,1,64)
    	go(p,1,n)
    	go(i,1,n)
    	go(j,1,n)
            {
    	    f[k][i][j]|=f[k-1][i][p]&f[k-1][p][j];
    	    if(f[k][i][j])a[i][j]=1;
    	}
        go(i,1,n)a[i][i]=0;
        go(p,1,n)
    	go(i,1,n)
    	go(j,1,n)
    	a[i][j]=min(a[i][j],a[i][p]+a[p][j]);
        printf("%lld
    ",a[1][n]);
        return 0;
    }
    
    
  • 相关阅读:
    【oracle】 DDL,DML,DCL区别
    【python】模块初识之random模块
    【python】模块初识之re模块
    【python】模块初识之time模块
    【python】属性和类方法
    【python】面向对象初识之封装
    【python】面向对象初识之多态
    【python】面向对象初识之继承
    【python】面向对象初识
    【python】二分查找
  • 原文地址:https://www.cnblogs.com/forward777/p/11716472.html
Copyright © 2020-2023  润新知