POJ 2449 A*+SPFA
A*算法求第k短路流程:
1)计算h[],即当前点到t的估计值
若为有向图,建立反向图求出h[]。若为无向图,可直接求解h[]。可通过SPFA求解。
2)A*搜索
每次找到新节点就直接加入队列,计算出估价函数f[]=g[]+h[],然后加入优先队列中。(此步不可优化,否则可能造成失解)
常用STL priority_queue实现,要注意默认是大根堆,可重载<实现小根堆。
3)若根入队k次,返回
ADD:
该题几个注意事项及优化:
a)若起始点h值==INF,不搜。
b)若一个点入队超过k次,不搜。
c)邻接表代替邻接矩阵,防止重边。
d)该题中若s==t,距离为0的路径不能计入。
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- #include <cstdlib>
- #include <cmath>
- #include <utility>
- #include <vector>
- #include <queue>
- #include <map>
- #include <set>
- #define max(x,y) ((x)>(y)?(x):(y))
- #define min(x,y) ((x)>(y)?(y):(x))
- #define INF 0x3f3f3f3f
- #define N 1005
- #define M 100005
- using namespace std;
- struct Edge
- {
- int y,w,ne;
- }e[M*],re[M*];
- int x,y,w,n,m,s,t,k;
- int be[N],all;
- int rbe[N],rall;
- int h[N],cnt[N];
- bool vis[N];
- struct Point
- {
- int x,g;
- bool operator < (const Point T) const
- {
- return g+h[x]>T.g+h[T.x];
- }
- };
- void add(int x, int y, int w)
- {
- e[all].y=y;
- e[all].w=w;
- e[all].ne=be[x];
- be[x]=all++;
- }
- void radd(int x, int y, int w)
- {
- re[rall].y=y;
- re[rall].w=w;
- re[rall].ne=rbe[x];
- rbe[x]=rall++;
- }
- void SPFA(int s)
- {
- queue< int > q;
- while(!q.empty())
- q.pop();
- for(int i=; i<=n; i++)
- {
- h[i]=INF;
- vis[i]=;
- }
- h[s]=;
- vis[s]=;
- q.push(s);
- while(!q.empty())
- {
- int u=q.front();
- q.pop();
- vis[u]=;
- for(int i=rbe[u]; i!=-; i=re[i].ne)
- {
- int v=re[i].y;
- if(h[v]>h[u]+re[i].w)
- {
- h[v]=h[u]+re[i].w;
- if(!vis[v])
- {
- vis[v]=;
- q.push(v);
- }
- }
- }
- }
- }
- int Astar(int s, int t, int k)
- {
- SPFA(t);
- if(h[s]==INF) return -;
- priority_queue< Point > q;
- while(!q.empty())
- q.pop();
- memset(vis,,sizeof(vis));
- memset(cnt,,sizeof(cnt));
- Point cur,nxt;
- cur.x=s;
- cur.g=;
- q.push(cur);
- while(!q.empty())
- {
- cur=q.top();
- q.pop();
- if((++cnt[cur.x])>k) continue;
- if(cnt[t]==k)
- return cur.g;
- for(int i=be[cur.x]; i!=-; i=e[i].ne)
- {
- nxt.x=e[i].y;
- nxt.g=cur.g+e[i].w;
- q.push(nxt);
- }
- }
- return -;
- }
- void init()
- {
- all=;
- memset(be,-,sizeof(be));
- rall=;
- memset(rbe,-,sizeof(rbe));
- }
- int main()
- {
- scanf("%d%d",&n,&m);
- init();
- for(int i=; i<m; i++)
- {
- scanf("%d%d%d",&x,&y,&w);
- add(x,y,w);
- radd(y,x,w);
- }
- scanf("%d%d%d",&s,&t,&k);
- if(s==t) k++;
- printf("%d\n",Astar(s,t,k));
- return ;
- }
- /*
- 2 4
- 1 2 1
- 1 2 2
- 1 2 3
- 2 1 5
- 1 2 5
- */
POJ 2449 A*+SPFA的更多相关文章
- poj 2449 Remmarguts' Date 【SPFA+Astar】【古典】
称号:poj 2449 Remmarguts' Date 意甲冠军:给定一个图,乞讨k短路. 算法:SPFA求最短路 + AStar 以下引用大牛的分析: 首先,为了说话方便,列出一些术语: 在启示式 ...
- POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang
题目大意:给你一个有向图,并给你三个数s.t 和 k ,让你求从点 s 到 点 t 的第 k 短的路径.如果第 k 短路不存在,则输出“-1” ,否则,输出第 k 短路的长度. 解题思路:这道题是一道 ...
- POJ 2449:Remmarguts' Date(A* + SPFA)
题目链接 题意 给出n个点m条有向边,源点s,汇点t,k.问s到t的第k短路的路径长度是多少,不存在输出-1. 思路 A*算法是启发式搜索,通过一个估价函数 f(p) = g(p) + h(p) ,其 ...
- poj 2449 Remmarguts' Date K短路+A*
题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...
- poj 2449(A*求第K短路)
题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...
- poj 2449 k短路+A*算法
http://poj.org/problem?id=2449 K短路的定义: 1.如果起点终点相同,那么0并不是最短路,而是要出去一圈回来之后才是最短路,那么第K短路也是一样. 2.每个顶点和每条边都 ...
- poj 2449 Remmarguts' Date(K短路,A*算法)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013081425/article/details/26729375 http://poj.org/ ...
- poj 2449 Remmarguts' Date (k短路模板)
Remmarguts' Date http://poj.org/problem?id=2449 Time Limit: 4000MS Memory Limit: 65536K Total Subm ...
- POJ 1860(spfa)
http://poj.org/problem?id=1860 题意:汇率转换,与之前的2240有点类似,不同的是那个题它去换钱的时候,是不需要手续费的,这个题是需要手续费的,这是个很大的不同. 思路: ...
随机推荐
- linux xampp常见问题
一.常见问题 1.安装xampp4linux后,只能本机(http://localhost)访问,局域网内其他机器无法访问 解答:在/opt/lampp/etc中修改httpd.conf,将Liste ...
- html+css学习笔记 5[表格、表单]
表格 -- 默认样式重置 表格标签: table 表格 thead 表格头 tbody 表格主体 tfoot 表格尾 tr 表格行 th 元素定义表头 ...
- 3044 矩形面积求并 - Wikioi
题目描述 Description 输入n个矩形,求他们总共占地面积(也就是求一下面积的并) 输入描述 Input Description 可能有多组数据,读到n=0为止(不超过15组) 每组数据第一行 ...
- Netty4.x中文教程系列(三) ChannelHandler
Netty4.x中文教程系列(四) ChannelHandler 上一篇文章详细解释了Hello World示例的代码.里面涉及了一些Netty框架的基础. 这篇文章用以解释ChannelHandl ...
- tomcat7.0.47 修改tomcat窗口名称
最近使用的是 apache - tomcat 集群,为了方便管理上想要修改tomcat命令窗口的名字来区分不同的tomcat,我在网上找了些资料,顺便总结一下,方便自己,方便他人 修改如下: 找到to ...
- CodeForces 173B Chamber of Secrets 二分图+最短路
题目链接: http://codeforces.com/problemset/problem/173/B 题意: 给你一个n*m的地图,现在有一束激光从左上角往左边射出,每遇到‘#’,你可以选择光线往 ...
- 【BestCoder】【Round#29】
T1 啊……a^b 与 c^d比较大小,我们可以两边取对数,转化成 log(a^b)=b*log(a) 和d*log(c) 这样就能直接算了……然后稍微搞一下精度什么的就A了=.= //BC #29 ...
- Enabled AWE
sp_configure RECONFIGURE GO sp_configure RECONFIGURE GO sp_configure RECONFIGURE GO sp_configure REC ...
- nodeJS实战
github代码托管地址: https://github.com/Iwillknow/microblog.git 根据<NodeJS开发指南>实例进行实战{{%并且希望一步步自己能够逐步将 ...
- IIS7.5 自定义Html/shtml/htm...后缀映射
以添加html后缀的文件的 映射为例: 1.打开iis管理器,点击 2.点击打开处理程序映射 3.添加托管处理程序映射 4.请求路径 *.html 类型: System.Web.UI.PageHand ...