次短路

次短路

广泛一点的定义是:在数值上比最短路大的一条最小的路径长度(有点像前驱)

(1) 双向SPFA求次短路

思路:处理出始点S,终点T到每个点的最短路径长度。枚举每条边,用这条边所连接的两个点所对应分别到S和T的长度更新次短路。

感性证明:不可能有比部分最短路+一条边还短的路径了

参考代码:

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N=5010;
const int M=100010;
int head[N],edge[M<<1],to[M<<1],next[M<<1],cnt;
void add(int u,int v,int w)
{
    edge[++cnt]=w;to[cnt]=v;next[cnt]=head[u];head[u]=cnt;
}
int diss[N],dist[N],n,m,used[N],shor,ans;
queue <int > q;
void spfa()
{
    q.push(1);
    memset(diss,0x3f,sizeof(diss));
    memset(used,0,sizeof(used));
    diss[1]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        used[u]=0;
        for(int i=head[u];i;i=next[i])
        {
            int v=to[i],w=edge[i];
            if(diss[v]>diss[u]+w)
            {
                diss[v]=diss[u]+w;
                if(!used[v])
                {
                    used[v]=1;
                    q.push(v);
                }
            }
        }
    }
    q.push(n);
    memset(dist,0x3f,sizeof(diss));
    memset(used,0,sizeof(used));
    dist[n]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        used[u]=0;
        for(int i=head[u];i;i=next[i])
        {
            int v=to[i],w=edge[i];
            if(dist[v]>dist[u]+w)
            {
                dist[v]=dist[u]+w;
                if(!used[v])
                {
                    used[v]=1;
                    q.push(v);
                }
            }
        }
    }
    ans=0x3f3f3f3f;
    shor=diss[n];
    for(int i=1;i<=n;i++)
        for(int j=head[i];j;j=next[j])
        {
            int v=to[j],w=edge[j];
            if(diss[i]+dist[v]+w!=shor)
                ans=min(ans,diss[i]+dist[v]+w);
        }
    printf("%d
",ans);
}
int main()
{
    scanf("%d%d",&n,&m);
    int u,v,w;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w),add(v,u,w);
    }
    spfa();
    return 0;
}

(2) Dijsktra求次短路

思路:在(dis)数组放两个,分别存当前最短路和次短路。最短只被最短更新,次短可以被当前点最短,前点最短,前点次短更新

没写代码。

原文地址:https://www.cnblogs.com/butterflydew/p/9235694.html