Roadblocks

博客介绍了次短路径问题的解法,以Roadblocks题目为例,采用Dijkstra算法先求出1和n的最短路,对于每条边 (x, y, z),通过公式Ans=Min{dist1[x]+z+distn[y]}(dist1[x]+z+distn[y]>dist1[n]) 来计算次短路径。

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

转载请注明出处:https://blog.youkuaiyun.com/Robertlyp/article/details/93485855

题见:Roadblocks
Solution
次短路径
先用Dijkstra求1和n的最短路
对于每条边 (x, y, z):
A n s = M i n { d i s t 1 [ x ] + z + d i s t n [ y ] } ( d i s t 1 [ x ] + z + d i s t n [ y ] > d i s t 1 [ n ] ) Ans = Min\{ dist_1[x] + z + dist_n[y]\}(dist_1[x]+z+dist_n[y] > dist_1[n]) Ans=Min{dist1[x]+z+distn[y]}(dist1[x]+z+distn[y]>dist1[n])

#include <iostream>
#include <queue>
#include <vector>
#include <climits>
#include <cstring>

using namespace std;

int n, r;
int b1[5010], bn[5010], d1[5010], dn[5010];
priority_queue<pair<int, int> > q;
vector<pair<int, int> > edge[5010];

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> r;
    memset(d1, 0x3f, sizeof d1);
    memset(dn, 0x3f, sizeof dn);
    d1[1] = dn[n] = 0;
    for (int i = 1; i <= r; i++)
    {
        int A, B, D;
        cin >> A >> B >> D;
        edge[A].push_back(make_pair(B, D));
        edge[B].push_back(make_pair(A, D));
    }
    q.push(make_pair(0, 1));
    while (q.size())
    {
        int x = q.top().second; q.pop();
        if (b1[x]) continue;
        b1[x] = 1;
        for (int i = 0; i < edge[x].size(); i++)
        {
            int y = edge[x][i].first, z = edge[x][i].second;
            if (d1[y] > d1[x] + z)
            {
                d1[y] = d1[x] + z;
                q.push(make_pair(-d1[y], y));
            }
        }
    }
    q.push(make_pair(0, n));
    while (q.size())
    {
        int x = q.top().second; q.pop();
        if (bn[x]) continue;
        bn[x] = 1;
        for (int i = 0; i < edge[x].size(); i++)
        {
            int y = edge[x][i].first, z = edge[x][i].second;
            if (dn[y] > dn[x] + z)
            {
                dn[y] = dn[x] + z;
                q.push(make_pair(-dn[y], y));
            }
        }
    }
    int ans = INT_MAX;
    for (int i = 1; i <= n; i++)
        for (int j = 0; j < edge[i].size(); j++)
        {
            int dis = d1[i] + edge[i][j].second + dn[edge[i][j].first];
            if (dis > d1[n] && dis < ans)
                ans = dis;
        }
    printf("%d\n", ans);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值