次短路

本文深入探讨了次短路算法的两种实现方法:A*算法和改进的Dijkstra算法。通过POJ3255例题,详细展示了如何利用优先队列和二维距离数组来求解次短路问题,为读者提供了清晰的代码模板。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、次短路

听名字也能知道,次短路就是求的第二短的路径,这里有两种解法

1、A*,上一篇博客写的就是关于A*的,A*用来求第k短的路径,当k==2时,即为次短路。

这里就不多叙述

2、其实就是在最短路上稍微修改一点点就好啦......

即将dis数组改为二维,dis[i][0]表示到i点的最短路,dis[i][1]表示到i点的次短路,然后每次比较更新每个点的两个值即可

二、

这里用poj3255作为例题给出模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define exp 1e-8
#define mian main
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ll long long
#define pb push_back
#define PI  acos(-1.0)
#define inf 0x3f3f3f3f
#define w(x) while(x--)
#define int_max 2147483647
#define lowbit(x) (x)&(-x)
#define gcd(a,b) __gcd(a,b)
#define pq(x)  priority_queue<x>
#define ull unsigned long long
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define pl(a,n) next_permutation(a,a+n)
#define ios ios::sync_with_stdio(false)
#define met(a,x) memset((a),(x),sizeof((a)))
using namespace std;
const int N=1e5+10;
int n,m,s,t;
struct node
{
    int v,c;
    node(int _v,int _c):v(_v),c(_c){}
    bool operator <(const node &p)const
    {
        return c>p.c;
    }
};
struct edge
{
    int v,cost;
    edge(int _v,int _cost):v(_v),cost(_cost){}
};
vector<edge>e[N];
int dis[N][2];
void add(int u,int v,int w)
{
    e[u].push_back(edge(v,w));
}
void dj()
{
    met(dis,inf);
    dis[s][0]=0;
    priority_queue<node>q;
    while(!q.empty())
        q.pop();
    q.push(node(s,0));
    node tmp(0,0);
    while(!q.empty()){
        tmp=q.top();
        q.pop();
        int u=tmp.v;
        if(dis[u][1]<tmp.c)   //剪枝,跟最短路中vis数组作用一样
            continue;
        for(int i=0;i<e[u].size();i++){
            int v=e[u][i].v;
            int cost=e[u][i].cost;
            int d=tmp.c+cost;
            if(dis[v][0]>d){
                swap(dis[v][0],d);
                q.push(node(v,dis[v][0]));
            }
            if(dis[v][1]>d&&dis[v][0]<d){
               dis[v][1]=d;
                q.push(node(v,dis[v][1]));
            }
        }
    }
}
int main()
{
    while(cin>>n>>m)
    {
        int x,y,z;
         for(int i=1;i<=n;i++)
           e[i].clear();
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        s=1,t=n;
         dj();
        cout<<dis[t][1]<<endl;
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值