次短路

次短路

概念:次短路是相对于最短路的,简单来说就是第二短的路径。

方法: dijkstradijkstradijkstra 找最短路的同时,维护一个次短路数组(dist2[]dist2[]dist2[])。

  1. 当 (到达目的节点的最短路) >>> (从队列中取出的值 + 当前点到目的点的距离)即 dist[v]>d+E[now][i].costdist[v] > d + E[now][i].costdist[v]>d+E[now][i].cost,则更新最短路和次短路, 即
    dist2[v]=dist[v];dist2[v] = dist[v];dist2[v]=dist[v];
    dist[v]=d+E[now][i].cost;dist[v] = d + E[now][i].cost;dist[v]=d+E[now][i].cost;
  2. 当 (到达目的节点的最短路) &lt;&lt;< (从队列中取出的值 + 当前点到目的点的距离)&lt;&lt;< (到达目的节点的次短路),只更新次短路,即
    dist2[v]=d+E[now][i].cost;dist2[v] = d + E[now][i].cost;dist2[v]=d+E[now][i].cost;
    注意:每次更新结束后都需要加入队列。

放道水题AC代码放道水题AC代码AC

// poj - 2355  Roadblocks
#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <string.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 5100;

struct edge {
    int to, cost;
    bool operator < (const edge &d) const{
        return cost > d.cost;
    }
};

std::vector<edge > E[MAXN];
void add_edge(int u, int v, int c) {
    E[u].push_back((edge){v, c});
}

int N, R, a, b, d;

int dist[MAXN];
int dist2[MAXN];
int dijkstra(int s) {
    memset(dist, INF, sizeof(dist));
    fill(dist2, dist2+N, INF);
    priority_queue<edge > pq;
    dist[s] = 0;
    pq.push((edge){s, dist[s]});
    while(!pq.empty()) {
        int now = pq.top().to;
        int d = pq.top().cost;
        pq.pop();
        if(dist2[now] < d) continue;
        for (int i = 0; i < E[now].size(); ++i) {
            int v = E[now][i].to;
            int d2 = d + E[now][i].cost;
            if(dist[v] > d2) {
                dist2[v] = dist[v];
                dist[v] = d2;
                pq.push((edge){v, dist[v]});
            }
            else if(dist[v] < d2) {
                if(dist2[v] > d2) {
                    dist2[v] = d2;
                    pq.push((edge){v, dist2[v]});
                }
            }
        }
    }
}

int main(int argc, char const *argv[])
{
    cin>>N>>R;
    for (int i = 0; i < R; ++i) {
        cin>>a>>b>>d;
        add_edge(a, b, d);
        add_edge(b, a, d);
    }
    dijkstra(1);
    cout<<dist2[N]<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值