ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

次短路问题

2020-02-02 15:00:41  阅读:180  来源: 互联网

标签:int 短路 问题 edge maxn d2 dis


1.次短路问题

次短路问题和最短路问题类似,我们可以想到次短路由什么转移而来?对于当前一个点,其次短路只可能由两种情况转移而来:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>

using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
typedef pair<int,int> pii;
struct Edge
{
    int nex,to,val;
}edge[maxn<<1];
int dis[maxn],dis2[maxn],head[maxn],tot=0;  //dis2[]保存次短路
int n,m;
void init()
{
    tot=0;
    memset(head,-1,sizeof(head));
}
void add(int from,int to,int val)
{
    edge[++tot].to=to;
    edge[tot].val=val;
    edge[tot].nex=head[from];
    head[from]=tot;
}
void solve(int s)
{
    priority_queue<pii, vector<pii>, greater<pii> > q;  //压入最短或次短距离
    memset(dis,inf,sizeof(dis));
    memset(dis2,inf,sizeof(dis2));
    dis[s]=0;
    q.push(make_pair(0,s));           //first是权值second是点
    while(!q.empty())
    {
        int v=q.top().second;       
        int d=q.top().first;
        q.pop();
        if(dis2[v]<d)  continue;     //取出的不是次短距离,抛弃
        for(int i=head[v];i!=-1;i=edge[i].nex)
        {
            int d2=d+edge[i].val;       //d为原点到i的最短距离或次短距离
            if(dis[edge[i].to]>d2)     //更新最短距离
            {
                swap(dis[edge[i].to],d2);
                q.push(make_pair(dis[edge[i].to],edge[i].to));
            }
            if(dis2[edge[i].to]>d2&&dis[edge[i].to]<d2) //更新次短距离
            {
                dis2[edge[i].to]=d2;
                q.push(make_pair(dis2[edge[i].to],edge[i].to));
            }
        }
        /*
        if(dis[edge[i].to]>d2)     //更新最短距离
            {
                dis2[edge[i].to]=dis[edge[i].to];
                dis[edge[i].to]=d2;
                q.push(make_pair(dis2[edge[i].to],edge[i].to));
                q.push(make_pair(d2,edge[i].to));
            }
            if(dis2[edge[i].to]>d2&&dis[edge[i].to]<d2) //更新次短距离
            {
                dis2[edge[i].to]=d2;
                q.push(make_pair(dis2[edge[i].to],edge[i].to));
            }
        */
    }
}

int main()
{
    init();
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i){
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        add(a,b,c);
        add(b,a,c);
    }
    solve(1);
    printf("%d\n",dis2[n]);
}

【题意】:求最短路以及次短路的条数(次短路必须只比最短路大一个单位)

#include<bits/stdc++.h>

using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
int dist[maxn][2],cnt[maxn][2],head[maxn];  //数组0表示最短,1表示次短
bool vis[maxn][2];
int n,m,tot;
struct Edge
{
    int nex,to,val;
} edge[maxn<<4];
void addedge(int from,int to,int val)
{
    edge[++tot].to=to;
    edge[tot].val=val;
    edge[tot].nex=head[from];
    head[from]=tot;
}
void dijkstra(int s)
{
    int pos,minn,k;
    for(int i=1; i<=n; i++)
        dist[i][0]=dist[i][1]=inf;
    memset(vis,false,sizeof(vis));
    memset(cnt,0,sizeof(cnt));
    cnt[s][0]=1;
    dist[s][0]=0;
    for(int i=1;i<=tot;i++)                
    {
        pos=-1;
        minn=inf;
        for(int j=1; j<=n; j++)
            if(!vis[j][0]&&minn>dist[j][0])         //找最短路,每个节点先更新最短,然后次短
            {
                k=0;
                minn=dist[j][0];
                pos=j;
            }
            else if(!vis[j][1]&&minn>dist[j][1])    //找次短路
            {
                k=1;
                minn=dist[j][1];
                pos=j;
            }
        if(pos==-1)     break;//如果找不到最短或者次短就结束
        vis[pos][k]=1;
        for(int j=head[pos];j!=-1;j=edge[j].nex)
        {
            int v=edge[j].to;
            int d=dist[pos][k]+edge[j].val;
            if(d<dist[v][0])                  //更新最短路长度及条数
            {
                dist[v][1]=dist[v][0];          
                cnt[v][1]=cnt[v][0];            
                dist[v][0]=d;                 
                cnt[v][0]=cnt[pos][k];          
            }
            else if(d==dist[v][0])            
                cnt[v][0]+=cnt[pos][k];
            else if(d<dist[v][1])             //更新次短路
            {
                dist[v][1]=d;
                cnt[v][1]=cnt[pos][k];
            }
            else if(d==dist[v][1])
                cnt[v][1]+=cnt[pos][k];
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        tot=0;
        memset(head,-1,sizeof(head));
        scanf("%d%d",&n,&m);
        int a,b,c,s,t;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            addedge(a,b,c);
        }
        scanf("%d%d",&s,&t);
        dijkstra(s);
        int ans=cnt[t][0];
        if(dist[t][1]==dist[t][0]+1)
            ans+=cnt[t][1];
        printf("%d\n",ans);
    }
}

次短路问题也可以用算法来解决。

标签:int,短路,问题,edge,maxn,d2,dis
来源: https://www.cnblogs.com/StungYep/p/12252237.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有