!-- Loading 底层遮罩 -->

次短路

次短路模板

做法

    在任何时候,如果发现了一条新的从 1 到 i 的路径,则该路径可能存在以下几种情况:

    1.该路径长度小于目前的 1 到 i 的最短路。此时的处理方式时将目前的次短路用目前的最短路替换,而最短路径替换为新路径。

    2.该路径长度大于目前次短路(也会大于目前最短路)直接舍去。

    3.该路径长度大于目前最短路且小于目前次短路。此时的处理方式时直接用这条路径替换当前次短路。

#include<iostream>
#include<cstring>
#include<queue>
#define maxn 100007
using namespace std;
struct edge {
    int to, val, nxt;
}g[maxn << 1];
int cnt, hd[maxn], dis[2][5050], N, R;
void add(int u, int v, int w)
{
    g[++cnt].val = w;
    g[cnt].to = v;
    g[cnt].nxt = hd[u];
    hd[u] = cnt;
}
struct node {
    int s, w;
    bool operator<(const node& a)const {
        return w > a.w;
    }
};
priority_queue<node> q;
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);  
    cin >> N >> R;
    for (int i = 1, u, v, w; i <= R; i++)
    {
        cin >> u >> v >> w;
        add(u, v, w);
        add(v, u, w);
    }
    memset(dis, 127, sizeof(dis));
    dis[0][1] = 0;
    q.push({ 1,0 });
    while (!q.empty())
    {
        int u = q.top().s, d = q.top().w;
        q.pop();
        if (d > dis[1][u])continue;//这里要十分注意,等于的时候不应该直接弹出
        for (int i = hd[u]; i; i = g[i].nxt)
        {
            int v = g[i].to, w = g[i].val;
            if (dis[0][v] > d + w)
            {
                dis[1][v] = dis[0][v];
                dis[0][v] = d + w;
                q.push({ v,dis[0][v] });
            }
            if (dis[0][v] < d + w && d + w < dis[1][v])
            {
                dis[1][v] = d + w;
                q.push({ v,dis[1][v] });
            }
        }
    }
    cout << dis[1][N];
    return 0;
}

 

posted @ 2022-05-02 21:59  Thinker-X  阅读(61)  评论(0)    收藏  举报