[最短路] 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值