[poj3255]次短路

Posted lh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[poj3255]次短路相关的知识,希望对你有一定的参考价值。

给出一张有n个点和m条双向边的图,要求求出1到n的次短路的长度。一条边可以多次通过。

输入格式:

第一行为两个整数n和m。接下来的m行每行三个整数ai,bi,vi,分别表示这条路连着的两个点和他的长度。

输出格式:

一个整数,表示次短路的长度。(次短路长度必须大于最短路,数据保证有解)

样例输入

样例输出

4 4
1 2 100
2 4 200
2 3 250
3 4 100

450

 

样例解释:

最短:1->2->4。

次短:1->2->3->4。

数据范围:

对于 100%的数据:1<=n、vi<=5000,1<=m<=100000。 

首先更新的条件有两个:小于最短距离,大于最短距离且小于次短距离

如果新更新出的值小于最短路的值,那么把最短路的值变成新更新的值,次短路的值变成最短路的值

注意:要把现最短路的值和现次短路的值都进堆

如果新更新出的值大于最短距离且小于次短距离,那么仅更新次短路的值,且将次短路的值入堆

同样出堆的条件也应放宽到小于等于次短路径

注意:初始化时仅有S的最短路长度为0,其他都为inf(包括次短路长度)

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int h[5100],to[200100],next[200100],k=0,cost[200100];
typedef pair<int,int> P;
priority_queue<P,vector<P>,greater<P> > q;
int dist[5100][2];
void ins(int u,int v,int w){next[++k]=h[u];h[u]=k;to[k]=v;cost[k]=w;}
void dij(int S)
{
    memset(dist,127/2,sizeof(dist));
    dist[S][0]=0;q.push(P(0,S)); 
    while(!q.empty())
    {
        P p=q.top();q.pop();int u=p.second;
        if(dist[u][1]<p.first)continue;
        for(int i=h[u];i;i=next[i])
        {
            int v=to[i];
            if(p.first+cost[i]<dist[v][0])
            {
                dist[v][1]=dist[v][0];dist[v][0]=p.first+cost[i];
                q.push(P(dist[v][0],v));q.push(P(dist[v][1],v)); 
            }
            else if(p.first+cost[i]<dist[v][1]&&p.first+cost[i]!=dist[v][0])
            {
                dist[v][1]=p.first+cost[i];
                q.push(P(dist[v][1],v)); 
            }
        }
    }
}
int main()
{
    freopen("short.in","r",stdin);freopen("short.out","w",stdout);
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y,z;scanf("%d%d%d",&x,&y,&z);ins(x,y,z);ins(y,x,z);
    }
    dij(1);
    printf("%d",dist[n][1]);
    return 0;
}

以上是关于[poj3255]次短路的主要内容,如果未能解决你的问题,请参考以下文章

poj3255

POJ-3255 Roadblocks---Dijkstra队列优化+次短路

POJ 3255 Roadblocks (次短路模板)

次短路 poj 3255

POJ3255 Roadblocks 次短路

POJ3255Roadblocks[次短路]