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
  • 相关阅读:
    C#面向对象
    CSS样式表---------第三章:样式属性
    CSS样式表-------第二章:选择器
    CSS样式表------第一章:样式表的基本概念
    解决Web部署 svg/woff/woff2字体 404错误
    sql server 2012 如何收缩事务日志
    input file类型,文件类型的限制
    C#对XML、JSON等格式的解析
    SQL实现表名更改,列名更改,约束更改
    sql 坐标距离排序计算距离(转)
  • 原文地址:https://www.cnblogs.com/sszywq/p/13933790.html
Copyright © 2011-2022 走看看