《Roadblocks》次短路问题

这里是一个求次短路问题,也就是除了最短路之外第二短的路.
这里我用dj…算法(不会拼)。
首先明确一点,次短路肯定是最短路上拿掉某一段换成第二短的.
对于一个点u,到它的次短路肯定是到它之前的某个点的最短路加上到它的距离,或者是到它前某个点的最短路加上到它的距离.
然后就能求解

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
const int N = 1e5+5;
const int M = 1e3+7;
#define INF INT_MAX
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define sd(a) scanf("%d",&a)
#define sld(a) scanf("%lld",&a)
#define sdd(a,b) scanf("%d %d",&a,&b)
#define sddd(a,b,c) scanf("%d %d %d",&a,&b,&c)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
#define pr_(a) printf("%d ",a)
#define _pr(a) printf(" %d",a)
struct Node
{
    int cost;
    int to;
};
vector<Node> v[N];
int dis[N],sec[N],vis[N];//sec存次短路
void dstk()
{
    memset(vis,0,sizeof(vis));
    dis[1] = 0;
    priority_queue<pii,vector<pii>,greater<pii> > Q;//前编号,后长度
    Q.push(mk(1,0));
    while(!Q.empty())
    {
        int pos = Q.top().first;
        int d = Q.top().second;
        Q.pop();
        if(sec[pos] < d) continue;//当这条路径比次短路还长.就不查看它了
            for(int i=0;i<v[pos].size();++i)
            {
                int y = v[pos][i].to,dan = v[pos][i].cost;
                int dl = d+dan;
                if(dis[y] > dl)
                {
                    swap(dis[y],dl);
                    Q.push(mk(y,dis[y]));
                }
                if(dl > dis[y] && dl < sec[y])
                {
                    sec[y] = dl;
                    Q.push(mk(y,sec[y]));
                }
            }
    }
}
int main()
{
    int n,r;
    sdd(n,r);
    for(int i=1;i<=n;++i) dis[i] = INF,sec[i] = INF;
    while(r--)
    {
        int x,y,z;
        sddd(x,y,z);
        Node p,q;
        p.cost = z;p.to = y;
        q.cost = z;q.to = x;
        v[x].pb(p);
        v[y].pb(q);
    }
    dstk();
    pr(sec[n]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值