poj2449-A*算法+优先队列+第k最短路

2023-12-08 22:38

本文主要是介绍poj2449-A*算法+优先队列+第k最短路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

点击打开链接

分析:A*算法主要由是估价函数f(n)=g(n)+h(n);其中g(n)代表当前的实际代价。h(n)是估计代价。算法的效率直接取决于h(n)的评价性。h(n)的设计思想是无限靠近(极限).

在本题中,g(n)代表从初始位置到当前x点所付出的代价。h(n)代表从当前x点到目标位置的估计代价。本题关键是怎样求h(n),每个点到目标点t不一定联通。也不好估价,

巧妙之处是:从目标t到初始位置s的最短路。即反向求最短路。这样h(n)的值是最低评估了。

代码;

#include<cstdio>
#include<queue>
#include<cstring>
#define N 1001
#define INF 1000000
using namespace std;struct qu{                                        //优先队列 int v,g,h;          qu(int V,int G,int H):v(V),g(G),h(H){}   //构造函数 bool operator<(const qu &a)const{       //运算符重载 return a.g+a.h<g+h;           //A_star 算法的体现之处 }
};struct node{int x,y,cost,next1,next2;
}edge[N*200];bool vis[N];
int s,t,k,n,m,cnt;
int hash[N],head[N],d[N];bool spfa()       //反向求最短路,即求评估函数h,结果保存在d【】中。 
{queue<int>q;int i,x,v;memset(vis,0,sizeof(vis));for(i=1;i<=n;i++) d[i]=INF;d[t]=0;q.push(t);while(!q.empty()){int x=q.front();q.pop();vis[x]=0;for(i=head[x];i!=-1;i=edge[i].next2){v=edge[i].x;if(d[v]>edge[i].cost+d[x]){d[v]=edge[i].cost+d[x];if(!vis[v]){vis[v]=1;q.push(v);	}}}}if(d[s]==INF) return false;return true;	
}int A_star()
{  int count[N],p;if(!spfa()) return -1;         //即判定是否连通,又求出了评估函数。 if(s==t) k++;                 //这个要注意。相同的不能认为第k短路是0,而是1,而这里求得为0,故要加1. memset(count,0,sizeof(count));priority_queue<qu>Q;Q.push(qu(s,0,d[s]));while(!Q.empty()){qu dx=Q.top();Q.pop();if(count[dx.v]==k) continue;if(++count[dx.v]==k&&dx.v==t) return dx.g; //因为是优先队列,第几次出列,即就是第k短路 for(int i=hash[dx.v];i!=-1;i=edge[i].next1){p=edge[i].y;if(count[p]==k) continue;Q.push(qu(p,dx.g+edge[i].cost,d[p]));}}return -1;
}void addate(int x,int y,int c)   //要求双向,故要两个表 
{edge[cnt].x=x;edge[cnt].y=y;edge[cnt].cost=c;edge[cnt].next1=hash[x];edge[cnt].next2=head[y];hash[x]=cnt;head[y]=cnt++;
}int main()
{int x,y,c,i;cnt=0;scanf("%d%d",&n,&m);	memset(head,-1,sizeof(head));memset(hash,-1,sizeof(hash));for(i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&c);addate(x,y,c);}scanf("%d%d%d",&s,&t,&k);printf("%d\n",A_star());return 0;
}


这篇关于poj2449-A*算法+优先队列+第k最短路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/471541

相关文章

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

SpringKafka错误处理(重试机制与死信队列)

《SpringKafka错误处理(重试机制与死信队列)》SpringKafka提供了全面的错误处理机制,通过灵活的重试策略和死信队列处理,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、Spring Kafka错误处理基础二、配置重试机制三、死信队列实现四、特定异常的处理策略五

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

Spring Boot整合消息队列RabbitMQ的实现示例

《SpringBoot整合消息队列RabbitMQ的实现示例》本文主要介绍了SpringBoot整合消息队列RabbitMQ的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录RabbitMQ 简介与安装1. RabbitMQ 简介2. RabbitMQ 安装Spring

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque