zoukankan      html  css  js  c++  java
  • 次短路

    次短路

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

    (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)数组放两个,分别存当前最短路和次短路。最短只被最短更新,次短可以被当前点最短,前点最短,前点次短更新

    没写代码。

  • 相关阅读:
    程序员版孔乙己
    痛!痛!痛!我们的好兄弟Git,一路走好!
    谈谈中台架构之交易中台
    一个单例还能写出花来吗?
    为什么数据库字段要使用NOT NULL?
    阿里二面:什么是mmap?
    退税不完全操作指南,我这样操作省了2000块!
    开源组件编排引擎LiteFlow发布里程碑版本2.5.0
    开源框架TLog核心原理架构解析
    对乱糟糟的日志说再见
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9235694.html
Copyright © 2011-2022 走看看