P1613 跑路

小A买了一个空间跑路器,每秒钟可以跑 2^k千米(k 是任意自然数)。
当然,这个机器是用longint 存的,所以总跑路长度不能超过其范围。
小A的家到公司的路可以看做一个有向图,小A 家为点 1,公司为点 n,每条边长度均为一千米。
小A想每天能醒地尽量晚,所以让你帮他算算,他最少需要几秒才能到公司。数据保证 1 到 n 至少有一条路径。

1. 倍增动态规划 + Floyd算法

int main()
{
    //如果没有环,不会超过6次倍增,存在环,这里需要取到long的上限
    bool reach[60][60][65];
    long graph[60][60];
    memset(reach,0,sizeof(reach));
    memset(graph,0x3f,sizeof(graph));
    int n; int m; //n个点
    cin>>n>>m;
    for(int i=0;i<m;i++){
        int from; int to;
        cin>>from>>to;
        reach[from][to][0] = true;
        graph[from][to] = 1;//权值皆为1
    }
    for(int k=0;k<64;k++)//倍增64次
        for(int i=1;i<=n;i++) //遍历n个点
            for(int j=1;j<=n;j++)//遍历n个点
                if(reach[i][j][k]==true)//如果当前可达,尝试找下一个点进行倍增,用j作为中间点
                    for(int l=1;l<=n;l++){
                        reach[i][l][k+1]|=reach[j][l][k];
                        if(reach[i][l][k+1]) graph[i][l] = 1;}
 
    //graph为最终权值图,根据该图计算最短路径
    for(int k=1;k<=n;k++)//作为中间点
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                graph[i][j] = min(graph[i][j],graph[i][k]+graph[k][j]);
    cout<<graph[1][n];
    return 0;
}
posted @ 2023-08-29 00:25  失控D大白兔  阅读(10)  评论(0编辑  收藏  举报