严格次短路,Dijkstra——POJ - 3255

题目链接

题目含义

一个人想去朋友家,最短路不走,想走次短路,而且长度严格小于最短路

题目分析

次短路的模板题,还是挺简单的

但是与求最短路不同

Dijstra算法里此时队列中dis最小的点的dis即是它的最短路,就将它出队处理接下来的点就行了

而求次短路时,如果这个点像求最短路一样出队的话,万一这个点的次短路没求好

那完了,你已经出队了

而且,你队列里装的dis不是指对应pos的最短路,而是指某一条可以到pos的路径长度(可能是最短路,可以是次短路,在一些求第k短时甚至可能是其他短路)

所以就不能像求最短路一样直接用dis[pos]代指(q.top()).dis而只能用(q.top()).dis

题目代码

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int maxn=1e5+7;
const int INF=0x3f3f3f3f;
typedef long long LL;
int head[5007],dis[5007][2];///dis[i][0]表示最短路,dis[i][1]表示次短路
int tot,n,r,a,b,d;
struct edge{
    int to,w,next;
}e[maxn*2];
struct node{
    int pos,dis;
    bool operator<(const node &x)const{
        return dis>x.dis;
    }
};
void add(int u,int v,int w){
    e[tot].to=v;
    e[tot].w=w;
    e[tot].next=head[u];
    head[u]=tot++;
}
void Dijkstra(){
    priority_queue<node>q;
    dis[1][0]=0;
    q.push((node){1,0});
    while(!q.empty()){
        node temp=q.top();q.pop();
        int u=temp.pos,dist=temp.dis;
        for(int i=head[u];i!=-1;i=e[i].next){
            int v=e[i].to;
            if(dis[v][0]>dist+e[i].w){
                dis[v][1]=dis[v][0];
                dis[v][0]=dist+e[i].w;
                q.push((node){v,dis[v][0]});
                q.push((node){v,dis[v][1]});
            }
            else if(dis[v][1]>dist+e[i].w&&dis[v][0]!=dist+e[i].w){
                dis[v][1]=dist+e[i].w;
                q.push((node){v,dis[v][1]});
            }
        }
    }
}
int main(){
    scanf("%d%d",&n,&r);
    tot=0;
    memset(head,-1,sizeof(head));
    memset(dis,INF,sizeof(dis));
    for(int i=1;i<=r;i++){
        scanf("%d%d%d",&a,&b,&d);
        add(a,b,d),add(b,a,d);
    }
    Dijkstra();
    printf("%d\n",dis[n][1]);
    return 0;
}

 

posted @ 2019-07-31 19:56  helman78  阅读(387)  评论(0编辑  收藏  举报