Roadblocks(poj 3255)

题意:给出n个点,m条双向边,求严格次短路。

/*
  先spfa预处理出起点到每个点的和每个点到终点的最短距离,然后枚举每条边(这条边必须走),计算此时的最短路径,得出严格次短路。
  正确性:因为对于一条最短路,它不可能把所有的边走完(应该很显然),那么我们枚举所有边,就一定会枚举到它没走的边,此时的最短路就可能是次短路。
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#define N 5010
#define M 100010
#define INF 500000000
using namespace std;
int head[N],dis1[N],dis2[N],vis[N],n,m;
struct node{
    int u,v,pre,t;
};node e[M*2];
void add(int i,int x,int y,int z){
    e[i].u=x;
    e[i].v=y;
    e[i].t=z;
    e[i].pre=head[x];
    head[x]=i;
}
void spfa1(int s){
    memset(dis1,127/3,sizeof(dis1));
    memset(vis,0,sizeof(vis));
    queue<int> q;
    dis1[s]=0;q.push(s);vis[s]=1;
    while(!q.empty()){
        int x=q.front();q.pop();vis[x]=0;
        for(int i=head[x];i;i=e[i].pre){
            if(dis1[e[i].v]>dis1[x]+e[i].t){
                dis1[e[i].v]=dis1[x]+e[i].t;
                if(!vis[e[i].v]){
                    vis[e[i].v]=1;
                    q.push(e[i].v);
                }
            }
        }
    }
}
void spfa2(int s){
    memset(dis2,127/3,sizeof(dis1));
    memset(vis,0,sizeof(vis));
    queue<int> q;
    dis2[s]=0;q.push(s);vis[s]=1;
    while(!q.empty()){
        int x=q.front();q.pop();vis[x]=0;
        for(int i=head[x];i;i=e[i].pre){
            if(dis2[e[i].v]>dis2[x]+e[i].t){
                dis2[e[i].v]=dis2[x]+e[i].t;
                if(!vis[e[i].v]){
                    vis[e[i].v]=1;
                    q.push(e[i].v);
                }
            }
        }
    }
}
void work(){
    for(int i=1;i<=m;i++){
        int x,y,z;scanf("%d%d%d",&x,&y,&z);
        add(i*2-1,x,y,z);add(i*2,y,x,z);
    }
    spfa1(1);
    spfa2(n);
    int shortest=dis1[n],ci=INF;
    for(int i=1;i<=2*m;i++){
        int len=dis1[e[i].u]+dis2[e[i].v]+e[i].t;
        if(len>shortest&&len<ci){
            ci=len;
        }
    }
    printf("%d\n",ci);
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(head,0,sizeof(head));
        memset(e,0,sizeof(e));
        work();
    }
    return 0;
}

 

posted @ 2016-11-11 19:26  karles~  阅读(215)  评论(0编辑  收藏  举报