`
yzmduncan
  • 浏览: 330387 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论
阅读更多

    所谓K短路,就是从s到t的第K短的路,第1短就是最短路。

    如何求第K短呢?有一种简单的方法是广度优先搜索,记录t出队列的次数,当t第k次出队列时,就是第k短路了。但点数过大时,入队列的节点过多,时间和空间复杂度都较高。

    A*是在搜索中常用的优化,一种启发式搜索。简单的说,它可以用公式表示为f(n) = g(n) + f(n),其中,f(n)是从s经由节点n到t的估价函数,g(n)是在状态空间中从s到n的实际代价,h(n)是从n到t的最佳路径估计代价。在设计中,要保证h(n)<= n到t的实际代价,这一点很重要,h(n)越接近真实值,速度越快。

    由于启发函数的作用,使得计算机在进行状态转移时尽量避开不可能产生最优解的分支,而选择相对较接近最优解的路径进行搜索,降低了时间和空间复杂度。

    算法过程:

    1. 将图反向,用dijstra+heap求出t到所有点的最短距离,目的是求所有点到点t的最短路,用dis[i]表示i到t的最短路,其实这就是A*的启发函数,显然:h(n)<= n到t的实际代价。

    2. 定义估价函数。我们定义g(n)为从s到n所花费的代价,h(n)为dis[n],显然这符合A*算法的要求。

    3. 初始化状态。状态中存放当前到达的点i,fi,gi。显然,fi=gi+dis[i]。初始状态为(S,dis[S],0),存入优先级队列中。

    4. 状态转移。假设当前状态所在的点v相邻的点u,我们可以得到转换:(V,fv,gv)-->(U,fu+w[v][u],gv+w[v][u])。

    5. 终止条件。每个节点最多入队列K次,当t出队列K次时,即找到解。

 

    例:POJ2449

    题意:裸的K短路。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAX = 1005;
int n,m;
int start,end,k;
struct Edge
{
    int w;
    int to;
    int next;
};
Edge e[100005];
int head[MAX],edgeNum;
int dis[MAX];   //dis[i]表示从i点到end的最短距离
bool vis[MAX];
int cnt[MAX];
vector<Edge> opp_Graph[MAX];

struct Node
{
    int f,g;    //f = g+dis[v]
    int v;      //当前到达的节点
    Node(int a, int b,int c):f(a),g(b),v(c){}
    bool operator < (const Node& a) const
    {
        return a.f < f;
    }
};

void addEdge(int from, int to, int w)
{
    e[edgeNum].to = to;
    e[edgeNum].w = w;
    e[edgeNum].next = head[from];
    head[from] = edgeNum++;
}

void dijikastra(int start)
{
    int i;
    memset(vis,0,sizeof(vis));
    for(i = 1; i <= n; i++)
        dis[i] = INF;
    dis[start] = 0;
    priority_queue<Node> que;
    que.push(Node(0,0,start));
    Node next(0,0,0);
    while(!que.empty())
    {
        Node now = que.top();
        que.pop();
        if(vis[now.v])              //从集合T中选取具有最短距离的节点
            continue;
        vis[now.v] = true;          //标记节点已从集合T加入到集合S中
        for(i = 0; i < opp_Graph[now.v].size(); i++)    //更新从源点到其它节点(集合T中)的最短距离
        {
            Edge edge = opp_Graph[now.v][i];
            if(!vis[edge.to] && dis[now.v] + edge.w < dis[edge.to])     //加不加前面的判断无所谓
            {
                dis[edge.to] = dis[now.v] + edge.w;
                next.f = dis[edge.to];
                next.v = edge.to;
                que.push(next);
            }
        }
    }
}

int A_Star()
{
    int i;
    priority_queue<Node> que;
    if(dis[start] == INF)
        return -1;
    que.push(Node(dis[start],0,start));
    Node next(0,0,0);
    while(!que.empty())
    {
        Node now = que.top();
        que.pop();
        cnt[now.v]++;
        if(cnt[end] == k)
            return now.f;
        if(cnt[now.v] > k)
            continue;
        for(i = head[now.v]; i != -1; i = e[i].next)
        {
            next.v = e[i].to;
            next.g = now.g + e[i].w;
            next.f = next.g + dis[e[i].to];
            que.push(next);
        }
    }
    return -1;
}

int main()
{
    int i;
    int from,to,w;
    edgeNum = 0;
    memset(head,-1,sizeof(head));
    memset(opp_Graph,0,sizeof(opp_Graph));
    memset(cnt,0,sizeof(cnt));
    scanf("%d %d",&n,&m);
    Edge edge;
    for(i = 1; i <= m; i++)
    {
        scanf("%d %d %d",&from,&to,&w);
        addEdge(from,to,w);
        edge.to = from;
        edge.w = w;
        opp_Graph[to].push_back(edge);
    }
    scanf("%d %d %d",&start,&end,&k);
    if(start == end)
        k++;
    dijikastra(end);
    int result = A_Star();
    printf("%d\n",result);
    return 0;
}

 

 

 

分享到:
评论

相关推荐

    找第K短路 c++ 图论

    ### 找第K短路 c++ 图论 #### 背景与问题描述 本篇文章主要探讨了在图论领域中寻找第K条最短路径的问题,并提供了使用C++实现的具体算法代码。在实际应用中,例如网络路由、城市规划等领域,常常需要找到连接两点...

    astar 第k短路

    ### A*算法求解第K短路径 #### A*算法简介 A*(A星)算法是一种在图形搜索中寻找从起点到终点的最短路径的算法。它结合了最佳优先搜索的最佳特性与统一成本搜索的完备性及最优性。A*算法的主要优点在于其高效性和...

    A-star和第k短路和次小生成树和Yen和MPS寻路算法.doc

    A-star算法、第k短路、次小生成树、Yen算法和MPS寻路算法。 A-star算法是一种静态路网中求解最短路最有效的方法。该算法的核心是估价函数f(n),它是节点n从初始点到目标点的估价函数。估价函数可以表示为f(n)=g(n)+...

    K短路(双扫描法)C++

    《K短路算法详解——基于C++的双扫描法实现》 K短路算法,也称为K最短路径(K Shortest Paths, KSP),是图论中的一个重要问题,广泛应用于网络优化、交通规划、社交网络分析等领域。本文将深入探讨如何使用C++语言...

    K最短路算法实现(KSP)

    《K最短路算法实现详解》 在计算机科学与图论领域,K最短路算法(K-Shortest Paths,简称KSP)是一项用于寻找网络中源节点到目标节点前K条最短路径的算法。它广泛应用于交通规划、网络优化、数据通信等多个领域。...

    求K短路的模板

    A* dijstra k短路 求法:反向建边 通过dijstra做预处理 最短路作为A*的评估函数 通过A* 将目标点出队列K次 如果原点和终点相同出栈K+1次

    神经网络在K短路路径优化中的并行计算.pptx

    - **K最短路径问题**:该问题的核心在于寻找从源点到汇点的一组最短路径,包括第1短路、第2短路等直至第K短路。这一问题本质上是一个优化问题,旨在最小化路径长度的同时考虑路径数量的限制。 - **整数线性规划(ILP...

    k短路算法说明和程序源码

    ### K短路算法详解 #### 一、算法背景与意义 K短路算法是一种用于寻找图中两个点间前K条最短路径的算法。它不仅适用于简单的无向图,也广泛应用于有向图的问题解决中。在实际应用中,如网络路由规划、交通路径规划...

    Yen算法求前K短路

    而`前k短路.ppt`可能是一个演示文稿,详细介绍了Yen算法的理论知识,包括算法的背景、原理、步骤以及可能的优化策略,如如何有效地存储和比较已找到的路径,以提高算法效率。 总的来说,Yen算法是一种高效寻找无向...

    k最短路程序,k短路算法,matlab

    在物流和网络优化领域,"K最短路"(K-Shortest Paths,简称KSP)算法是一项重要的计算技术,用于寻找图中的多条最短路径。这些路径可能在不同的条件下具有不同的最优性,比如时间最短、距离最短或者成本最低。在...

    K最短路问题MATLAB实现

    对于K最短路问题,首先找出两点之间的所有路径,然后利用K最短路算法,将最短路、次短路、第三最短路等计算出来,存入数组中。该matlab程序具有很好的通用性,希望对大家有用。 说明:findpath.m文件可计算出任意两...

    k最短路 程序 c 与java版本!

    在计算机科学领域,"k最短路"(k Shortest Paths,KSP)问题是一个经典图论问题,它涉及到寻找图中的k条具有最短路径的路径。这个问题在路由算法、网络规划、交通工程以及多目标优化等领域有着广泛应用。本讨论将...

    我的地K算法

    在实现这个算法时,`myK.cpp`和`复件 第K短路.cpp`可能是两个不同的实现版本或者包含不同功能的代码文件。`myK.cpp`可能包含了主程序和核心算法的实现,包括路径的表示、优先队列的管理以及路径更新的逻辑。而`复件 ...

    进阶01——考虑换乘的基于路径长度的所有点间K短路算法(计算结果)

    这里提到的"进阶01——考虑换乘的基于路径长度的所有点间K短路算法"是一种优化的路径搜索算法,旨在解决在有向或无向图中寻找多个最短路径的问题。K短路算法不仅找到一条最短路径,而是找到前K条最短路径,以提供更...

    图论- k 短路.rar

    《图论 - K 短路》是一份深入探讨图论中的一个重要概念——K 短路的资料。在计算机科学和图论中,K 短路问题是指寻找一个图中的最短路径集合,这些路径连接相同的两个顶点,并且路径数量为 K。这一问题在诸如交通...

    k短路算法-word

    ### K短路算法详解 #### 一、引言 在图论中,寻找两点之间的最短路径是一项基本而重要的任务。随着应用场景的多样化,仅找到一条最短路径往往不足以满足需求,例如在网络路由选择、城市规划等领域,可能需要考虑多...

    第K条最短路的算法介绍.doc

    第 K 条最短路的算法介绍 在实际应用中,需要知道多条最短路的问题称为 K 最短路问题,这类问题在通信网络中非常重要,为解决这类问题,引入了二重扫除算法。该算法主要应用二重扫除算法,通过推广的求极小值运算与...

    acm算法秘籍

    acm算法书,acmer必用的算法书。 目录 语言相关 常见基础错误 基础知识 枚举 模拟 ...次短路与第K短路 最近公共祖先 LCA 最小生成树 Kruskal 最小树形图 一般图的最大匹配 最大流 Dinic 最小割 费用流

Global site tag (gtag.js) - Google Analytics