所谓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;//严格最短路的判断条件为 cnt[end] == k&&now.f>min(zuiduanlu)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短路+严格第K短路相关推荐

  1. k近邻算法之 k值的选择

    k近邻算法之 k值的选择 举例说明: K值过小:  [过拟合] ​ 容易受到异常点的影响   [如:美人鱼本身就是喜剧片,假如统计的时候记为动作片,则对预测值的影响太大] k值过大:  [欠拟合] ​ ...

  2. 第k大 or 第k小 or 中位数

    c++里面有模板,这里不赘述.主要是c语言实现. 主要思想是递归+快排 1.用一个数组,进行原址选择,缺点是只能进行一次. 将一个数组以某一个元素a作为基准(这里选取最后一个),将这个数组划分,使得左 ...

  3. 机器学习 —— 基础整理(三)生成式模型的非参数方法: Parzen窗估计、k近邻估计;k近邻分类器...

    本文简述了以下内容: (一)生成式模型的非参数方法 (二)Parzen窗估计 (三)k近邻估计 (四)k近邻分类器(k-nearest neighbor,kNN) (一)非参数方法(Non-param ...

  4. POJ 3613 快速幂+Floyd变形(求限制k条路径的最短路)

    题意:       给你一个无向图,然后给了一个起点s和终点e,然后问从s到e的最短路是多少,中途有一个限制,那就是必须走k条边,路径可以反复走. 思路:       感觉很赞的一个题目,据说证明是什 ...

  5. Python,得到列表最小k个数或最大k个数的索引

    如果是直接得到最小或最大k个数,那么直接排序即可.但是如果要得到索引,那么不能排序,或者你排序时附带数据的下标.本文通过两种方法来展示怎么得到最小k个数的索引,一种是直接使用min()函数得到列表的最 ...

  6. k均值算法 二分k均值算法_如何获得K均值算法面试问题

    k均值算法 二分k均值算法 数据科学访谈 (Data Science Interviews) KMeans is one of the most common and important cluste ...

  7. 找出无序数组中最小的k个数(top k问题)

    2019独角兽企业重金招聘Python工程师标准>>> 给定一个无序的整型数组arr,找到其中最小的k个数 该题是互联网面试中十分高频的一道题,如果用普通的排序算法,排序之后自然可以 ...

  8. k均值算法 二分k均值算法_使用K均值对加勒比珊瑚礁进行分类

    k均值算法 二分k均值算法 Have you ever seen a Caribbean reef? Well if you haven't, prepare yourself. 您见过加勒比礁吗? ...

  9. K线理论--单根K线形态

    1. K线图 日K线是根据股价(指数)一天的走势中形成的四个价位即:开盘价,收盘价,最高价,最低价绘制而成的. 开盘价: 每个交易日的第一笔成交价格 收盘价: 每个交易日的最后一笔成交价格 最高价\最 ...

最新文章

  1. 2022-2028年中国硅藻土产业发展态势及市场发展策略报告
  2. 九九乘法表Python+Java,你知道多少?
  3. 关于modelsim 6.4a遇到的问题
  4. 看完就懂的编辑页面如何巧妙处理时间
  5. PYB Nano 开发板的完整设计文档
  6. 【教程】如何正确的写一个Lemon/Cena的SPJ(special judge)
  7. 编写Linux Shell脚本的最佳实践
  8. VS2013/VS2017 Visual Assist X安装及破解
  9. Android系统生成jks签名
  10. 期末考试之排名次java_2020超星尔雅《JavaWeb应用开发》期末测试答案
  11. 计算机应用技术的代码081401,学科、专业名称(代码).doc
  12. 2021年进销存管理软件商户门店使用热度前十名排行榜
  13. 万字长文保姆级教你制作自己的多功能QQ机器人
  14. VM(虚拟机)Ubuntu打不开
  15. 数据结构二叉树的链式存储
  16. python0.618方法
  17. T46:字符串转换成整数(Java)
  18. Linux 【权限,粘滞位】
  19. C#,索尼偏光相机(Polarization Camera)传感器IMX250和专用SDK简介
  20. API 生成淘宝数据包 拍拍数据包 差异

热门文章

  1. 2021年本溪高考成绩查询,2021年本溪高考状元名单公布 今年本溪高考状元是谁资料和分数...
  2. android 自定义对话框 demo,自定义dialog对话框获取EditText数据demo
  3. iOS 使用 MailCore2
  4. 【跟着我们学Golang】Go语言全平台安装
  5. centos7同一服务器安装两个或多个Tomcat
  6. Redux源码全篇浅读
  7. JeeSite 4.0 内置功能模块规划
  8. 为什么从1970年1月1日开始
  9. Intellij IDEA 新建一个EJB工程(三)
  10. win8: 清除iframe的缓存