• POJ3255--次短路


    求1到N的次短路,到某个顶点v的次短路有两种可能,一是到其他某个顶点u的最短路+edge(u,v)二是到其他某个点u的次短路+edge(u,v);

    因此在松弛的时候不仅要记录最短路,同时也要记录次短路

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    #include<string>
    #include<queue>
    #define INF 1e6
    using namespace std;
    const int maxn = 5005;
    struct node
    {
        int d,u;
        bool operator < (const node& rhs) const{
            return d > rhs.d;
        }
    };
    struct Edge
    {
        int from,to,dist;
        Edge(int u,int v,int d):from(u),to(v),dist(d){}
    };
    
    int n,m;
    vector<Edge> edges;//保存边的信息
    vector<int> g[maxn];//保存的边在edges数组里的编号;
    int d[maxn],d2[maxn];//最短距离,次短距离
    
    void addedge(int from,int to,int dist)//跟刘汝佳学的。。
    {
        edges.push_back((Edge){from,to,dist});
        edges.push_back((Edge){to,from,dist});
        int k = edges.size();
        g[from].push_back(k-2);
        g[to].push_back(k-1);
    }
    
    void dijkstra(int s)
    {
        priority_queue<node> que;
        for(int i = 1; i <= n; ++i){ d[i] = d2[i]= INF;}
        d[s] = 0;
    
        que.push((node){0,s});
        while(!que.empty())
        {
            node x = que.top();que.pop();
            int u = x.u;
            if(d2[u] < x.d) continue;//如果次短距离比这个节点的d值还小。。说明没有更新的必要
            for(int i = 0; i < g[u].size(); ++i)
            {
                Edge& e = edges[g[u][i]];
                int p = x.d + e.dist;//待更新的值,从这个节点进行松弛操作,注意这里的x.d可能是最短距离也可能是次短距离。
                if(d[e.to] > p)
                {
                    swap(d[e.to],p);//如果最短距离比这个P还大,那么要换一换这个值;这样可以省掉一些讨论
                    que.push((node){d[e.to],e.to});
                }
                if(d2[e.to] > p&&d[e.to] < p)//这种p值介于最短与次短之间时要更新次短的距离。
                {
                    d2[e.to] = p;
                    que.push((node){d2[e.to],e.to});//次短也可能对以后的结果有影响,所以也加入队列。
                }
            }
        }
    }
    int main()
    {
        //freopen("in","r",stdin);
        scanf("%d%d",&n,&m);
        int from,to,dist;
        for(int i = 0; i < m; ++i)
        {
            scanf("%d%d%d",&from,&to,&dist);
            addedge(from,to,dist);
        }
        dijkstra(1);
        cout<<d2[n]<<endl;
    }
  • 相关阅读:
    Java8新特性3 Stream
    注解
    Base64编码
    代理
    Cglib
    快照
    Java安全模式
    Hibernet缓存详解
    中文文档
    JDK1.8时间日期函数
  • 原文地址:https://www.cnblogs.com/Norlan/p/4776006.html
Copyright © 2020-2023  润新知