zoukankan      html  css  js  c++  java
  • luogu P1613 跑路 题解 (倍增 && 最短路)

    这道题的思路非常巧妙,如果两点之间的距离是$2^k$,那么就建一条长度为1的边,然后再跑一遍最短路就好了。

    推的方法就是$f(i, j, len) = 1$ 如果 $f(i, k, len - 1) = 1$ 并且$f(k, j, len - 1) = 1$,其中$f(i, j, len)$指的是$i$到$j$是否有长度为$2^{len}$的边

    有意思的是,如果一条路径是要重复走的,比如$i$和$j$之间有两条边,那么两个$2^0$的边存在,就可以推出$f(i, i)$存在$2^1$的边,可以看出这种情况是不会遗漏的。

    代码如下

    #include <cstdio>
    using namespace std;
    const int N = 51;
    int dis[N][N][N], ans[N][N];
    int main() {
        int n, m;
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= m; i++) {
            int u, v;
            scanf("%d %d", &u, &v);
            dis[u][v][0] = ans[u][v] = 1;
        }
        for (int len = 1; len <= 32; len++)
            for (int k = 1; k <= n; k++)
                for (int i = 1; i <= n; i++)
                    for (int j = 1; j <= n; j++)
                        if (dis[i][k][len - 1] == 1 && dis[k][j][len - 1] == 1)
                            dis[i][j][len] =  1, ans[i][j] = 1;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++) 
                if (i != j && ans[i][j] != 1)
                    ans[i][j] = (1 << 29);
        for (int k = 1; k <= n; k++)
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= n; j++)
                    if (ans[i][k] + ans[k][j] < ans[i][j])
                        ans[i][j] = ans[i][k] + ans[k][j];
        printf("%d", ans[1][n]);    
        return 0;        
    }
  • 相关阅读:
    js中return、return true、return false的区别
    flask,中间键
    flask,自定义中间件
    flask,闪现
    flask获取前端发送过来的数据
    flask中的如何将后端写前端的代码设置session
    flask中的正则匹配
    flask中的四剑客 及其他参数
    支付宝接口
    flasks框架简介
  • 原文地址:https://www.cnblogs.com/cminus/p/12492910.html
Copyright © 2011-2022 走看看