Poj3255 Roadblocks (次短路)

贝茜把家搬到了一个小农场,但她常常回到 FJ 的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。
贝茜所在的乡村有 R(1≤R≤10^5)条双向道路,每条路都连接了所有的 N(1≤N≤5000)个农场中的某两个。贝茜居住在农场 1,她的朋友们居住在农场 N(即贝茜每次旅行的目的地)。
贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且一条路可以重复走多次。当然第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。


严格次短路

首先我们要明确,最短路只能从最短路转移过来

但是次短路可以从最短路或次短路转移过来

然后我们在Dij中记录一个最短路

然后此题有一个坑点,就是可以重复走

例如:

 

这个图的最短路是1,次短路是3,从1到2再到1再到2

所以为了转移,我们在开始的时候就要把从1到1的此段路赋为正无穷,否则无法支持从2再走回来

下面给出代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
inline int rd(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
inline void write(int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
    return ;
}
struct node{
    int u,v;
    int set;
    bool operator<(const node x) const{return u>x.u;}
};
int head[100006],nxt[200006],to[200006],v[200006];
int total=0;
void add(int x,int y,int z){
    total++;
    to[total]=y;
    v[total]=z;
    nxt[total]=head[x];
    head[x]=total;
    return ;
}
int n,m;
priority_queue <node> Q;
int dis[100006],dis2[100006];
int book[100006];
int vis[100006];
void dij(int x){
    memset(dis,127,sizeof(dis));
    memset(dis2,127,sizeof(dis2));
    dis[x]=0;
    node h;
    h.v=x,h.u=0;
    Q.push(h);
    while(!Q.empty()){
        node h=Q.top();
        Q.pop();
        if(book[h.v]&&vis[h.v]) continue;
        if(h.set==1) book[h.v]=1;
        else vis[h.v]=1;
        for(int e=head[h.v];e;e=nxt[e]){
            dis2[to[e]]=min(dis2[to[e]],dis2[h.v]+v[e]);
            if(dis[to[e]]>dis[h.v]+v[e]){
                dis2[to[e]]=dis[to[e]];
                dis[to[e]]=dis[h.v]+v[e];
                node k;
                k.v=to[e],k.u=dis[to[e]],k.set=1;
                Q.push(k);
            }
            else if(dis2[to[e]]>dis[h.v]+v[e]&&dis[h.v]+v[e]>dis[to[e]]){
                dis2[to[e]]=dis[h.v]+v[e];
                node k;
                k.v=to[e],k.u=dis2[to[e]],k.set=2;
                Q.push(k);
            }
            if(dis2[h.v]+v[e]>dis[to[e]]) dis2[to[e]]=min(dis2[to[e]],dis2[h.v]+v[e]);
        }
    }
    return ;
}
int main(){
    n=rd(),m=rd();
    for(int i=1;i<=m;i++){
        int x=rd(),y=rd(),z=rd();
        add(x,y,z),add(y,x,z);
    }
    dij(1);
    write(dis2[n]);
    return 0;
}

 

posted @ 2018-10-25 15:29  Bruce--Wang  阅读(148)  评论(0编辑  收藏  举报