• Luogu1613 跑路-倍增+Floyd


    Solution

    挺有趣的一道题, 仔细想想才想出来

    先用$mp[i][j][dis]$ 是否存在一条 $i$ 到 $j$ 的长度为 $2^{dis}$ 的路径。

    转移 :

    1 for (int dis = 1; dis < base; ++dis)
    2         for (int k = 1; k <= n; ++k)
    3             for (int i = 1; i <= n; ++i) if (mp[i][k][dis - 1])
    4                 for (int j = 1; j <= n; ++j) if (mp[k][j][dis - 1])
    5                     mp[i][j][dis] = 1;

    若$mp[i][j][dis] = 1$, 则把 $f[i][j]$ 记为$1$

    然后再用$f[i][j]$ 去跑$Floyd$。 这样找出的路径 一定是最短的(因为能合成 $2^dis$ 的路径都已经被记录了

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rd read()
     5 using namespace std;
     6 
     7 const int N = 55;
     8 const int base = 32;
     9 
    10 int mp[N][N][N], f[N][N];
    11 int n, m;
    12 
    13 int read() {
    14     int X = 0, p = 1; char c = getchar();
    15     for (; c > '9' || c < '0'; c = getchar())
    16         if (c == '-') p = -1;
    17     for (; c >= '0' && c <= '9'; c = getchar())
    18         X = X * 10 + c - '0';
    19     return X * p;
    20 }
    21 
    22 void cmin(int &A, int B) {
    23     if (A > B) A = B;
    24 }
    25 
    26 int main()
    27 {
    28     n = rd; m = rd;
    29     memset(f, 63, sizeof(f));
    30     for (int i = 1; i <= m; ++i) {
    31         int u = rd, v = rd;
    32         mp[u][v][0] = 1;
    33     }
    34     for (int dis = 1; dis < base; ++dis)
    35         for (int k = 1; k <= n; ++k)
    36             for (int i = 1; i <= n; ++i) if (mp[i][k][dis - 1])
    37                 for (int j = 1; j <= n; ++j) if (mp[k][j][dis - 1])
    38                     mp[i][j][dis] = 1;
    39     for (int dis = 0; dis < base; ++dis)
    40         for (int i = 1; i <= n; ++i)
    41             for (int j = 1; j <= n; ++j) if (mp[i][j][dis])
    42                 f[i][j] = 1;
    43     for (int k = 1; k <= n; ++k)
    44         for (int i = 1; i <= n; ++i)
    45             for (int j = 1; j <= n; ++j)
    46                 cmin(f[i][j], f[i][k] + f[k][j]);
    47     printf("%d
    ", f[1][n]);
    48 }
    View Code
  • 相关阅读:
    常用的Intent.Action(转)
    Android存储--SharedPreferences
    Linux虚拟机网络配置
    SSH的两种登录方式以及配置
    Docker学习のC/S模式
    Docker学习のDocker镜像
    Docker学习のDocker中部署静态页网站
    Docker学习のWindows下如何访问Docker本身的虚拟机
    Docker学习のDocker的简单应用
    Docker学习の更改Docker的目录
  • 原文地址:https://www.cnblogs.com/cychester/p/9809810.html
Copyright © 2020-2023  润新知