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的更多相关文章

  1. poj 2449 Remmarguts&#39; Date 【SPFA+Astar】【古典】

    称号:poj 2449 Remmarguts' Date 意甲冠军:给定一个图,乞讨k短路. 算法:SPFA求最短路 + AStar 以下引用大牛的分析: 首先,为了说话方便,列出一些术语: 在启示式 ...

  2. POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang

    题目大意:给你一个有向图,并给你三个数s.t 和 k ,让你求从点 s 到 点 t 的第 k 短的路径.如果第 k 短路不存在,则输出“-1” ,否则,输出第 k 短路的长度. 解题思路:这道题是一道 ...

  3. POJ 2449:Remmarguts' Date(A* + SPFA)

    题目链接 题意 给出n个点m条有向边,源点s,汇点t,k.问s到t的第k短路的路径长度是多少,不存在输出-1. 思路 A*算法是启发式搜索,通过一个估价函数 f(p) = g(p) + h(p) ,其 ...

  4. poj 2449 Remmarguts' Date K短路+A*

    题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...

  5. poj 2449(A*求第K短路)

    题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...

  6. poj 2449 k短路+A*算法

    http://poj.org/problem?id=2449 K短路的定义: 1.如果起点终点相同,那么0并不是最短路,而是要出去一圈回来之后才是最短路,那么第K短路也是一样. 2.每个顶点和每条边都 ...

  7. poj 2449 Remmarguts' Date(K短路,A*算法)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013081425/article/details/26729375 http://poj.org/ ...

  8. poj 2449 Remmarguts' Date (k短路模板)

    Remmarguts' Date http://poj.org/problem?id=2449 Time Limit: 4000MS   Memory Limit: 65536K Total Subm ...

  9. POJ 1860(spfa)

    http://poj.org/problem?id=1860 题意:汇率转换,与之前的2240有点类似,不同的是那个题它去换钱的时候,是不需要手续费的,这个题是需要手续费的,这是个很大的不同. 思路: ...

随机推荐

  1. Log4Net学习【一】

    如果项目上过线的话,那你一定知道Log是多么重要.为什么说Log重要呢?因为上线项目不允许你调试,你只能通过Log来分析问题.这时打一手好Log的重要性绝不亚于写一手好代码.项目出问题时,你要能拿出L ...

  2. [SC] OpenSCManager FAILED 1722

    在服务器A(windows server 2008 r2)执行如下命令访问远端服务器B(windows server 2003)的服务运行状况: sc \\servername query " ...

  3. android中设置Animation 动画效果

    在 Android 中, Animation 动画效果的实现可以通过两种方式进行实现,一种是 tweened animation 渐变动画,另一种是 frame by frame animation ...

  4. BZOJ 2763: [JLOI2011]飞行路线 spfa dp

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=2763 题解: d[x][kk]表示从s到x用了kk次免费机会的最少花费. 代码: #in ...

  5. [转载]DirectoryEntry配置IIS7出现ADSI Error:未知错误(0x80005000)

    一.错误情况 环境:win7+iis7.0 DirectoryEntry配置IIS7出现如下错误 或者是 下面一段代码在IIS6.0下运转正常,但IIS7.0下运转会出错: System.Direct ...

  6. PE工具

    PE编辑工具 Stud_PE v. 2.4.0.1 PE工具,用来学习PE格式十分方便. http://www.cgsoftlabs.ro/ 汉化版:http://bbs.pediy.com/show ...

  7. java Socket用法详解(转)

    在客户/服务器通信模式中, 客户端需要主动创建与服务器连接的 Socket(套接字), 服务器端收到了客户端的连接请求, 也会创建与客户连接的 Socket. Socket可看做是通信连接两端的收发器 ...

  8. HDU 1546 Idiomatic Phrases Game(最短路,Dijsktra,理解题意很重要)

    题目 1.注意因为要判断能不能到达,所以要在模版里面判断k有没有更新. 2.看懂题目意思和案例的解法很重要. #define _CRT_SECURE_NO_WARNINGS //题目大意:现要进行单词 ...

  9. 【leetcode】Add Two Numbers(middle) ☆

    You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...

  10. python之self (转)

    首先明确的是self只有在类的方法中才会有,独立的函数或方法是不必带有self的.self在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数. self名称不是必须的,在python中self ...