zoukankan      html  css  js  c++  java
  • 次短路(模板)

     次短路模板

    #include <bits/stdc++.h>
    #include <cstring>
    #include <queue>
    using namespace std;
    const int N = 5005, M = 2e5 + 5;
    int n,m,u,v,w;
    struct Edge{
        int to,d;
    };
    struct node{
        int to, d, st; //st代表这个节点的状态
        bool friend operator<(const node& a, const node& b){
            if(a.d != b.d)
                return a.d > b.d;
        }
    };
    int d1[N], d2[N];
    bool vis[N][2]; //2种状态 0代表最短路 1代表次短路
    vector<node>G[N];
    void djkstra()
    {
        memset(d1, 0x3f, sizeof(d1));
        memset(d2, 0x3f, sizeof(d2));
        d1[1] = 0; //最开始次短路没有 所以d2不用更新
        priority_queue<node> q;
        q.push({1, 0, 0});
        while (!q.empty())
        {
            node t = q.top();
            q.pop();
            int now = t.to, st = t.st;
            int dis=t.d;    //注意这里为什么要用 dis = t.d.
            /*按照普通最短路来说,我们取出的这个点肯定离起点最近的点,(距离是 t.d)所以这里的dis
            也可以用 dis=dis[now]=t.d 来表示。但是这里我们有两个dis数组,我们不好判断,取得是dis1(存的最短路),
            还是dis2(存的次短路),所我们就可以让 dis= t.d,就可以不用判断是 dis1 还是dis2 了,这里取得肯定是最短的了,
            然后利用dis进行更新和松弛操作。
            */
            if (vis[now][st])
                continue; //最短路贪心的思想 每种状态节点遍历一次
            vis[now][st] = true;
            int _size=G[now].size();   //小优化,降低复杂度。
            for (int i=0;i<_size;i++)
            {
                int v = G[now][i].to;
                int w = G[now][i].d + dis;   //注意这个dis;
                if (w < d1[v]){
                    d2[v] = d1[v];
                    d1[v] = w;
                    q.push({v, d2[v], 1}); //因为它的状态改变了 所以也要入队
                    q.push({v, d1[v], 0}); //0代表以最短路状态入队
                }
                else if (w < d2[v] && d1[v] < w)    //严格最短路 次短路不能和最短路相同
                {
                    d2[v] = w;
                    q.push({v, d2[v], 1});
                }
            }
    
        }
    }
    int main(){
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i++){
            scanf("%d%d%d", &u, &v, &w);
            G[u].push_back({v,w});
            G[v].push_back({u,w});
    
        }
        djkstra();
        printf("%d
    ", d2[n]);
        return 0;
    }
    View Code
  • 相关阅读:
    MAUI预览版发布 (.NET 6 Preview2)
    ASP.NET Core 基础系列(6)(中间件)
    ASP.NET Core 基础系列(5)(appSetting)
    ASP.NET Core 基础系列(4)(Startup)
    ASP.NET Core 基础系列(3)(启动设置)
    ASP.NET Core 基础系列(2)(托管模型)
    ASP.NET Core 基础系列(1)(Main方法)
    Android开发学习之路-PopupWindow和仿QQ左滑删除
    部分病毒进程任务管理器终止不怎么办
    intellij idea 历史版本下载地址
  • 原文地址:https://www.cnblogs.com/sszywq/p/13933790.html
Copyright © 2011-2022 走看看