Not The Best 严格第二短路 A*第k短路或者次短路算法

Robin has moved to a small village and sometimes enjoys returning to visit one of his best friends. He does not want to get to his old home too quickly, because he likes the scenery along the way. He has decided to take the second-shortest rather than the shortest path. He knows there must be some second-shortest path.

The countryside consists of R bidirectional roads, each linking two of the N intersections, conveniently numbered from 1 to N. Robin starts at intersection 1, and his friend (the destination) is at intersection N.

The second-shortest path may share roads with any of the shortest paths, and it may backtrack i.e., use the same road or intersection more than once. The second-shortest path is the shortest path whose length is longer than the shortest path(s) (i.e., if two or more shortest paths exist, the second-shortest path is the one whose length is longer than those but no longer than any other path).

Input

Input starts with an integer T (≤ 10), denoting the number of test cases.

Each case contains two integers N (1 ≤ N ≤ 5000) and R (1 ≤ R ≤ 105). Each of the next R lines contains three space-separated integers: u, v and w that describe a road that connects intersections u and v and has length w (1 ≤ w ≤ 5000).

Output

For each case, print the case number and the second best shortest path as described above.

Sample Input

2

3 3

1 2 100

2 3 200

1 3 50

4 4

1 2 100

2 4 200

2 3 250

3 4 100

Sample Output

Case 1: 150

Case 2: 450


题目大意:问1-n的严格的第二短路是多少

题目思路:

两种方法:A*搜第k短路或者 spfa跑严格次短路

A*需要注意的事项,因为 为严格次短路所以我们要记录一下 上一个次小值是多少,不同即可.

次短路需要注意的事项,当不满足第一个时 第二个还需要加一个 条件才能成为次短路,dis[e]>u.w+edge[i].w即可

具体看代码:

A*:54 ms

#include <bits/stdc++.h>
#include<stdio.h>
#include<vector>
#pragma GCC optimize(2)
typedef long long ll;
typedef unsigned long long ull;
const int mod=998244353;
const int maxn=2e5+5;
const ll INF=100000000000005;
using namespace std;
ll n,m;
ll cnt=0,cnt1=0;
int head[maxn];
ll dis[maxn];
bool vis[maxn];
struct edg{
    int e,next;
    ll w;
}edge[maxn];
struct node
{
    ll id,g;
    friend bool operator<(node a,node b)
    {
        return a.g+dis[a.id]>b.g+dis[b.id];
    }
};
void restart()
{
    memset(head,-1,sizeof(head));
    cnt=0;
    cnt1=0;
}
void addedge1(int u,int v,ll w)//双向最短路无所谓反向,单向最短路需要反向存图
{
    edge[cnt]=edg{v,head[u],w};
    head[u]=cnt++;
    edge[cnt]=edg{u,head[v],w};
    head[v]=cnt++;
}
void spfa()
{
    for(int i=1;i<=n;i++) dis[i]=INF,vis[i]=false;
    queue<int>q;
    dis[n]=0;vis[n]=true;q.push(n);
    while(!q.empty())
    {
        int u=q.front();q.pop();vis[u]=false;
        for(int i=head[u];~i;i=edge[i].next)
        {
            int e=edge[i].e;
            if(dis[e]>dis[u]+edge[i].w)
            {
                dis[e]=dis[u]+edge[i].w;
                if(!vis[e])
                {
                    vis[e]=true;
                    q.push(e);
                }
            }
        }
    }
}
ll A_start()
{
    int cot=0;
    ll pre=-1;
    priority_queue<node>q;
    q.push(node{1,0});
    while(!q.empty())
    {
        node u=q.top();q.pop();
        if(u.id==n)
        {
            if(u.g!=pre) {cot++;pre=u.g;}
            if(cot==2) return u.g;
        }
        for(int i=head[u.id];~i;i=edge[i].next)
        {
            int e=edge[i].e;
            q.push(node{e,u.g+edge[i].w});
        }
    }
}
int main()
{
    int cas=0;
    int T;scanf("%d",&T);
    while(T--)
    {
        restart();
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int x,y;ll z;
            scanf("%d%d%lld",&x,&y,&z);
            addedge1(x,y,z);
        }
        spfa();
        printf("Case %d: %lld\n",++cas,A_start());
    }
    return 0;
}

改进次短路:108ms

#include <bits/stdc++.h>
#include<stdio.h>
#include<vector>
#pragma GCC optimize(2)
typedef long long ll;
typedef unsigned long long ull;
const int mod=998244353;
const int maxn=3e5+5;
const ll INF=100000000000005;
using namespace std;
ll n,m;
ll dis[maxn],dis1[maxn];
bool vis[maxn];
int head[maxn];
ll cnt=0;
struct node{
    int e,next;
    ll w;
}edge[maxn];
struct N{
    int id;
    ll w;
};
void restart()
{
    memset(head,-1,sizeof(head));
    cnt=0;
}
void addedge(int u,int v,ll w)
{
    edge[cnt]=node{v,head[u],w};
    head[u]=cnt++;
}
void spfa()
{
    for(int i=1;i<=n;i++) dis[i]=dis1[i]=INF,vis[i]=false;
    queue<N>q;dis[1]=0;
    vis[1]=true;N s;s.w=0;s.id=1;q.push(s);
    while(!q.empty())
    {
        N u=q.front();q.pop();
        for(int i=head[u.id];~i;i=edge[i].next)
        {
            int e=edge[i].e;
            if(dis[e]>u.w+edge[i].w)
            {
                dis1[e]=dis[e];
                dis[e]=u.w+edge[i].w;
                q.push(N{e,dis[e]});
            }
            else if(dis1[e]>u.w+edge[i].w&&u.w+edge[i].w>dis[e])
            {
                dis1[e]=u.w+edge[i].w;
                q.push(N{e,dis1[e]});
            }
        }
    }
}
int main()
{
    int cas=0;
    int T;scanf("%d",&T);
    while(T--)
    {
        restart();
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int x,y;ll z;
            scanf("%d%d%lld",&x,&y,&z);
            addedge(x,y,z);
            addedge(y,x,z);
        }
        spfa();
        printf("Case %d: %lld\n",++cas,dis1[n]);
    }
    return 0;
}

也做了一个比较:即A*比一般搜索速度要快

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
9225次浏览 83人参与
# 你的实习产出是真实的还是包装的? #
1689次浏览 40人参与
# 巨人网络春招 #
11300次浏览 223人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7416次浏览 42人参与
# 简历第一个项目做什么 #
31519次浏览 327人参与
# 重来一次,我还会选择这个专业吗 #
433317次浏览 3926人参与
# 米连集团26产品管培生项目 #
5651次浏览 214人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
186924次浏览 1120人参与
# 牛客AI文生图 #
21402次浏览 238人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152278次浏览 887人参与
# 研究所笔面经互助 #
118859次浏览 577人参与
# 简历中的项目经历要怎么写? #
309978次浏览 4189人参与
# AI时代,哪些岗位最容易被淘汰 #
63343次浏览 799人参与
# 面试紧张时你会有什么表现? #
30482次浏览 188人参与
# 你今年的平均薪资是多少? #
212996次浏览 1039人参与
# 你怎么看待AI面试 #
179816次浏览 1231人参与
# 高学历就一定能找到好工作吗? #
64302次浏览 620人参与
# 你最满意的offer薪资是哪家公司? #
76425次浏览 374人参与
# 我的求职精神状态 #
447969次浏览 3128人参与
# 正在春招的你,也参与了去年秋招吗? #
363209次浏览 2637人参与
# 腾讯音乐求职进展汇总 #
160568次浏览 1110人参与
# 校招笔试 #
470199次浏览 2962人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务