[最短路] aw1128. 信使(单源最短路建图+Floyd算法+最短路理解+模板题)

Posted Ypuyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[最短路] aw1128. 信使(单源最短路建图+Floyd算法+最短路理解+模板题)相关的知识,希望对你有一定的参考价值。

1. 题目来源

链接:1128. 信使

相关链接:

2. 题目解析

题目抽象:每个点接收到信的最短时间就是起点到该点的最短距离。 则问题转化为求起点到每个点最短距离的最大值,即可。

单源,无向图,无负权边,数据范围很小很小。最短路算法都能做。 在此写了最简单的 floyd 算法,注意先循环枚举 k


单源最短路的 dist 数组存的就是源点到个点的最短路嗷,我们之前只是关注了源点到终点的最短路距离,其实 dist[k] 存的就是源点到 k 点的最短路距离。

所以,不管用哪种最短路算法求完,遍历一遍 dist[i] 数组,求个最大值出来就行了。


注意:

  • 本题乍一看类似一个最小生成树,但是最小生成树是每个点到集合的最短距离,而不是每个点到 1 号点起点的最短距离。理解为最小生成树是错误的。
  • 本题可能有重边,在使用 Floyd 时需要选择一个边权的最小值
  • 当边权为 1 时,可用 bfs

时间复杂度 O ( n 3 ) O(n^3) O(n3)

空间复杂度 O ( n 2 ) O(n^2) O(n2)


Floyd

#include <bits/stdc++.h>

using namespace std;

const int N = 105;

int n, m;
int f[N][N];

int main() {
    scanf("%d%d", &n, &m);
    
    memset(f, 0x3f, sizeof f);
    for (int i = 0; i < N; i ++ ) f[i][i] = 0;  // 这个是必要的,但是本题不加也可以过,主对角线必然为 0,不加不为 0
    while (m -- ) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        f[a][b] = f[b][a] = min(f[a][b], c);        // 防止有重边
    }
    
    // 先循环 k
    for (int k = 1; k <= n; k ++ )
        for (int i = 1; i <= n; i ++ ) 
            for (int j = 1; j <= n; j ++ ) 
                f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
    
    int res = 0;
    for (int i = 1; i <= n; i ++ ) res = max(res, f[1][i]);
    
    if (res == 0x3f3f3f3f) res = -1;
    printf("%d\\n", res);
    
    return 0;
}

以上是关于[最短路] aw1128. 信使(单源最短路建图+Floyd算法+最短路理解+模板题)的主要内容,如果未能解决你的问题,请参考以下文章

第三章 图论未完成

[最短路] aw920. 最优乘车(单源最短路建图+bfs最短路模型+知识理解+好题)

[最短路] aw903. 昂贵的聘礼(单源最短路建图+超级源点+知识理解+好题)

[最短路] aw1129. 热浪(单源最短路建图+spfa循环队列+模板题)

[最短路] aw1127. 香甜的黄油(单源最短路建图+模板题)

[最短路] aw1126. 最小花费(单源最短路建图+知识理解+代码细节+好题)