第二短路

oj1220

贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。

贝茜所在的乡村有R(1<=R<=100,000)条双向道路,每条路都联结了所有的N(1<=N<=5000)个农场中的某两个。贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地)。

贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且,一条路可以重复走多次。当然咯,第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。

第二短路顾名思义要比第一短路要长,必剩余其他路短,所以比较是肯定要比较两次的啦,那么对于第二短路我们也要让它尽可能的短,所以我们用第一短路来寻找第二短路;

所以我们开两个数组,dis1,dis2,分别表示第一短路和第二短路;

所以

if(dis1[v]>dis1[x]+a[i].v)
{
dis2[v]=dis1[v];

dis1[v]=dis1[x]+a[i].v;
if(!vis[v]) vis[v]=1,q.push(v);
}
else if(dis1[x]+a[i].v<dis2[v]&&dis1[x]+a[i].v>dis1[v])
{//寻找满足条件的第二短路,二个条件是为了满足能够更新dis2(因为只有满足小于除最短路外的所有路)
dis2[v]=dis1[x]+a[i].v;
if(!vis[v]) q.push(v),vis[v]=1;
}
if(dis2[x]+a[i].v<dis2[v])
{//第二短路也需要找到最短路,比较更新;
dis2[v]=dis2[x]+a[i].v;
if(!vis[v]) q.push(v),vis[v]=1;

}

这样不断更新第二短路,就找到我们想要的answer啦;

代码

#include<bits/stdc++.h>
using namespace std;
#define N 5010
#define M 100010
int n,lin[N],tot,vis[N],dis1[N],xx,yy,vv,m,dis2[N];
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch))    {if(ch==‘-‘) f=-1;ch=getchar();}
    while(isdigit(ch))    {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
struct gg
{
    int y,next,v;
}a[M<<1];
inline void init(int xx,int yy,int vv)
{
    a[++tot].y=yy;
    a[tot].next=lin[xx];
    a[tot].v=vv;
    lin[xx]=tot;
}
inline void spfa()
{
    queue<int> q;
    memset(vis,0,sizeof(vis));
    memset(dis1,127,sizeof(dis1));
    memset(dis2,127,sizeof(dis2));
    dis1[1]=0;vis[1]=1;q.push(1);
    while(!q.empty())
    {
        int x=q.front();q.pop();vis[x]=0;
        for(int i=lin[x];i;i=a[i].next)
        {
            int v=a[i].y;
            if(dis1[v]>dis1[x]+a[i].v)
            {
                dis2[v]=dis1[v];
                dis1[v]=dis1[x]+a[i].v;
                if(!vis[v]) vis[v]=1,q.push(v);
            }
            else if(dis1[x]+a[i].v<dis2[v]&&dis1[x]+a[i].v>dis1[v])
            {
                dis2[v]=dis1[x]+a[i].v;
                if(!vis[v]) q.push(v),vis[v]=1;
            }
            if(dis2[x]+a[i].v<dis2[v])
            {
                dis2[v]=dis2[x]+a[i].v;
                if(!vis[v]) q.push(v),vis[v]=1;
            }
        }
    }
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=m;i++)
    {
        xx=read();yy=read();vv=read();
        init(xx,yy,vv);
        init(yy,xx,vv);
    }
    spfa();
    cout<<dis2[n]<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/Tyouchie/p/10259312.html

时间: 2024-08-04 14:15:38

第二短路的相关文章

bzoj1726 [Usaco2006 Nov]Roadblocks第二短路

1726: [Usaco2006 Nov]Roadblocks第二短路 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 826  Solved: 394[Submit][Status] Description 贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友.贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路. 贝茜所在的乡村有R(1<=R<=100,000)条双向

【最短路】LightOJ 1099 - Not the Best 第二短路

点击打开链接 题意:求第二短路,题目定义:一定要大于最短路      并且路可以重复走: 开二维数组 d[N][2] 分别记录最短路和第二短路 #include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream> #include <algorithm> #include <sstream> #includ

[SPFA][jzyzoj1220]第二短路

题面就不给了= =就是求从1到n的第二短路 因为从1到1的路径还要再求一次,所以不能用dijkstra的方法进行松弛,这时候需要我们使用spfa 以下是策略: 1.当前求得最短路小于已知最短路时,先将第二短路进行更新(需要将新的第二短路和旧的最短路进行比较),再将第一短路进行更新: 2.当前求得最短路等于已知最短路时,将第二短路进行更新(需要将新的第二短路与旧的第二短路进行比较): 3.当前求得最短路大于已知最短路时,将第二短路进行更新(将求得最短路与第二短路进行比较): 其余部分就是SPFA的

1726: [Usaco2006 Nov]Roadblocks第二短路

1726: [Usaco2006 Nov]Roadblocks第二短路 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 835  Solved: 398[Submit][Status] Description 贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友.贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路. 贝茜所在的乡村有R(1<=R<=100,000)条双向

BZOJ 1726: [Usaco2006 Nov]Roadblocks第二短路( 最短路 )

从起点和终点各跑一次最短路 , 然后枚举每一条边 , 更新answer ----------------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue&g

最短路【bzoj1726】: [Usaco2006 Nov]Roadblocks第二短路

1726: [Usaco2006 Nov]Roadblocks第二短路 Description 贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友.贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路. 贝茜所在的乡村有R(1<=R<=100,000)条双向道路,每条路都联结了所有的N(1<=N<=5000)个农场中的某两个.贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地). 贝茜选

次短路[SPFA]

Description 贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友.贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路. 贝茜所在的乡村有R(1<=R<=100,000)条双向道路,每条路都联结了所有的N(1<=N<=5000)个农场中的某两个.贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地). 贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且,一条路可

[K短路] SDOI2010 魔法猪学院

魔法猪学院 题目背景 感谢@kczno1 @X_o_r 提供hack数据 题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的:元素与元素之间可以互相转换:能量守恒--. 能量守恒--iPig 今天就在进行一个麻烦的测验.iPig 在之前的学习中已经知道了很多种元素,并学会了可以转化这些元素的魔法,每种魔法需要消耗 iPig 一定的能量.作为 PKU 的顶尖

8.20 usaco

summary:14 1.k短路 2.tarjan缩无向图点 3.复习了SA 4.差分约束 5.求第二短路 洛谷3824:dfs优化背包.开始的时候mle了,然后我就把a[i],w[i]去掉....就A了.优化空间... #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(in