P1119 灾后重建

这篇博客介绍了一种利用Floyd算法解决在给定时间限制下,从村庄a到村庄b的最短路径问题。Floyd算法的本质是一个动态规划策略,通过寻找最优中转站以缩短两点间的距离。博客提供了详细的代码实现,包括输入村庄重建时间、构建马路连接、Floyd算法的迭代过程,以及在指定时间范围内查询最短路径的方法。在解决此类问题时,Floyd算法能有效地处理多点间最短路径的计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接

题意

n个村庄的编号从0 - n-1,现在又m条马路连接,但是每条马路有一个连通的时间,你需要回答q个问题,问你a到b在第t天的时候的最短路径是多少?

思路

用来做Floyd练手的。
首先要知道Floyd算法的本质,它实质是一个dp,可以这么说,一个点到另外一个点,它们之间有n个中转站,你现在要找一个使这两个点的距离最近的中转站,就是这么个意思。
回到这个题,这个题可以用Dijkstra或者SPFA。现在想一想Floyd,题中告诉了你每个村庄完成重建的时间,并且给你的是递增的顺序,这样我们就省了给时间排序的步骤。这个时候我们一次遍历每个节点,以这个节点为中转站,来进行更新,这个时候中转站的重建时间要比给定的时间要小,然后在来求两个点之间的最短距离即可。后面再来看问的两个点的时间是否在给定的范围内,如果在我们就输出,反之则输出“-1”。

#include <bits/stdc++.h>

using namespace std;

const int N = 210, inf = 0x3f3f3f3f;

int n, m;
int t[N];
int d[N][N];

void Floyd(int x)
{
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < n; j ++)
            d[i][j] = min(d[i][j], d[i][x] + d[x][j]);
}

void solve()
{
    cin >> n >> m;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < n; j ++)
            if (i == j) d[i][j] = 0;
            else d[i][j] = inf;

    for (int i = 0; i < n; i ++) cin >> t[i];
    while (m --)
    {
        int a, b, c; cin >> a >> b >> c;
        d[a][b] = d[b][a] = c;
    }

    int cur = 0;
    int q; cin >> q;
    while (q --)
    {
        int a, b, c; cin >> a >> b >> c;
        while (t[cur] <= c && cur < n) { Floyd(cur); cur ++; }

        if (t[a] > c || t[b] > c || d[a][b] == inf) cout << "-1" << endl;
        else cout << d[a][b] << endl;
    }
}

signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    solve();

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值