POJ——2449Remmarguts' Date(A*+SPFA)
| Time Limit: 4000MS | Memory Limit: 65536K | |
| Total Submissions: 26504 | Accepted: 7203 |
Description
"Prince Remmarguts lives in his kingdom UDF – United Delta of Freedom. One day their neighboring country sent them Princess Uyuw on a diplomatic mission."
"Erenow, the princess sent Remmarguts a letter, informing him that she would come to the hall and hold commercial talks with UDF if and only if the prince go and meet her via the K-th shortest path. (in fact, Uyuw does not want to come at all)"
Being interested in the trade development and such a lovely girl, Prince Remmarguts really became enamored. He needs you - the prime minister's help!
DETAILS: UDF's capital consists of N stations. The hall is numbered S, while the station numbered T denotes prince' current place. M muddy directed sideways connect some of the stations. Remmarguts' path to welcome the princess might include the same station
twice or more than twice, even it is the station with number S or T. Different paths with same length will be considered disparate.
Input
sideway from A-th station to B-th station with time T.
The last line consists of three integer numbers S, T and K (1 <= S, T <= N, 1 <= K <= 1000).
Output
Sample Input
2 2
1 2 5
2 1 4
1 2 2
Sample Output
14
以前对A*有所耳闻,看得懂但是不知道如何实现,然后通过这道题有了一点理解……,这题做了两遍,第一次是看着别人的代码写的,第二次隔了段时间自己按照自己的理解写了下1A,理解一个算法还是非常重要的……
A*以我的理解就是给搜索算法一个大致的导向,尽量不往不必要的方向去搜索,也许也是因此叫做启发式搜索算法,就拿普通BFS比较吧,也就是一个退化了的A*,没有任何的导向,完全按照压入队列的时间顺序进行搜索,比如一个任意一点都可以站立的地图,人在中间,而目的地在右上角,显然BFS在到达目的地之前一定会对地图中大部分包括跟目的地相反方向的那些地方都搜索过,即越走越远,但是BFS不知道这些,只知道一层一层地扩展,即使走反了,如果有用标记或者染色,会发现地图上大部分无用、完全不必要的地区都被标记或染色过……因此BFS在数据范围较大的时候是比较慢的
而A*不一样,比BFS多了一个估价(启发)函数。先引用别的博主的一段话
所谓A*就是启发式搜索..说白了就是给BFS搜索一个顺序使得搜索更加合理减少无谓的搜索..如何来确定搜索的顺序?..也就是用一个值来表示这个值为f[x]..每次搜索取f[x]最小的进行拓展...f[x]=h[x]+g[x]其中h[x]就是当前搜索时的实际代价...估价函数要小于是对当前点到目标的代价的估计..这个估计必须小于等于实际值~~否则会出错...A*的关键也就是构造g[x]..
在图的搜索里面构造g[x]用的比较多的是欧氏距离、曼哈顿距离、切比雪夫距离(这个比较高端感觉不太用的上……)上面的紫色字体非常重要,这就是为什么要用反向的SPFA来做这题的原因,因为反着从T的单源的最短路放到正向的就不一定是某一点Si的最短路了,就可以保证反着是一定小于等于实际值的。这题还有一个小坑点就是如果一开始起点就是终点,那必须要绕一圈再回来,即k短路不能一开始就为0,VIS数组也不需要,首先这是k短路,其次这是A*启发式的,不会无脑遍历……然后就差不多可以做了……
代码:
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define MM(x,y) memset(x,y,sizeof(x))
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int M=100010;
const int N=10010;
struct info
{
int to;
int pre;
int dx;
};
struct A
{
int cur;
int g;
int h;
bool operator<(const A &b)const
{
return g+h>b.g+b.h;
}
};
info E[M],rE[M];
int head[M],rhead[M],d[N],cnt,rcnt;
priority_queue<pii>Q;
priority_queue<A>Qa;
void init()
{
MM(head,-1);
MM(rhead,-1);
MM(d,INF);
while (!Q.empty())
Q.pop();
while (!Qa.empty())
Qa.pop();
cnt=rcnt=0;
}
void add(info edge[],int &c,int Head[],int s,int t,int d)
{
edge[c].to=t;
edge[c].dx=d;
edge[c].pre=Head[s];
Head[s]=c++;
}
void spfa(int s)
{
d[s]=0;
Q.push(pii(-d[s],s));
while (!Q.empty())
{
int now=Q.top().second;
Q.pop();
for (int i=rhead[now]; ~i; i=rE[i].pre)
{
int v=rE[i].to;
if(d[v]>d[now]+rE[i].dx)
{
d[v]=d[now]+rE[i].dx;
Q.push(pii(-d[v],v));
}
}
}
}
int main(void)
{
int n,m,i,j,a,b,c,s,t,k;
while (~scanf("%d%d",&n,&m))
{
init();
for (i=0; i<m; i++)
{
scanf("%d%d%d",&a,&b,&c);
add(rE,rcnt,rhead,b,a,c);
add(E,cnt,head,a,b,c);
}
scanf("%d%d%d",&s,&t,&k);
spfa(t);
int r=-1;
A S;
S.cur=s;
S.g=0;
S.h=d[s];
Qa.push(S);
if(s==t)
k++;
while (!Qa.empty())
{
A now=Qa.top();
Qa.pop();
if(now.cur==t)
{
if(--k==0)
{
r=now.g;
break;
}
}
for (i=head[now.cur]; ~i; i=E[i].pre)
{
A Next=now;
int v=E[i].to;
Next.cur=v;
Next.g+=E[i].dx;
Next.h=d[v];
Qa.push(Next);
}
}
printf("%d\n",r);
}
return 0;
}
POJ——2449Remmarguts' Date(A*+SPFA)的更多相关文章
- POJ:2449-Remmarguts' Date(单源第K短路)
Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 33081 Accepted: 8993 Des ...
- POJ 2449:Remmarguts' Date(A* + SPFA)
题目链接 题意 给出n个点m条有向边,源点s,汇点t,k.问s到t的第k短路的路径长度是多少,不存在输出-1. 思路 A*算法是启发式搜索,通过一个估价函数 f(p) = g(p) + h(p) ,其 ...
- POJ 3279 Fliptile(翻格子)
POJ 3279 Fliptile(翻格子) Time Limit: 2000MS Memory Limit: 65536K Description - 题目描述 Farmer John kno ...
- POJ - 3308 Paratroopers(最大流)
1.这道题学了个单词,product 还有 乘积 的意思.. 题意就是在一个 m*n的矩阵中,放入L个敌军的伞兵,而我军要在伞兵落地的瞬间将其消灭.现在我军用一种激光枪组建一个防御系统,这种枪可以安装 ...
- POJ 1274 The Perfect Stall || POJ 1469 COURSES(zoj 1140)二分图匹配
两题二分图匹配的题: 1.一个农民有n头牛和m个畜栏,对于每个畜栏,每头牛有不同喜好,有的想去,有的不想,对于给定的喜好表,你需要求出最大可以满足多少头牛的需求. 2.给你学生数和课程数,以及学生上的 ...
- poj 1364 King(差分约束)
题意(真坑):傻国王只会求和,以及比较大小.阴谋家们想推翻他,于是想坑他,上交了一串长度为n的序列a[1],a[2]...a[n],国王作出m条形如(a[si]+a[si+1]+...+a[si+ni ...
- poj 1201 Intervals(差分约束)
做的第一道差分约束的题目,思考了一天,终于把差分约束弄懂了O(∩_∩)O哈哈~ 题意(略坑):三元组{ai,bi,ci},表示区间[ai,bi]上至少要有ci个数字相同,其实就是说,在区间[0,500 ...
- POJ 3259 Wormholes (Bellman_ford算法)
题目链接:http://poj.org/problem?id=3259 Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submis ...
- POJ 1006 Biorhythms (中国剩余定理)
在POJ上有译文(原文右上角),选择语言:简体中文 求解同余方程组:x=ai(mod mi) i=1~r, m1,m2,...,mr互质利用中国剩余定理令M=m1*m2*...*mr,Mi=M/mi因 ...
随机推荐
- Android 面试总结~~~
一.面试中的问题 通过这几天的面试,总结了自己在面试过程中问到的问题,部分问题已经给出了答案,还有部分问题,还未有时间整理出来. ListView出现闪图.图片错乱原因解决方案 函数式编程 (Lamb ...
- HDU 1561 The more, The Better (树形DP,常规)
题意:给一个森林,n个节点,每个点有点权,问若从中刚好选择m个点(选择某点之前必须先选择了其父亲),使得这m个点权之和最大为多少? 思路: 比较常规.就是DFS一次,枚举在子树中可能选择的k个点(注意 ...
- 洛谷 2299 Mzc和体委的争夺战
题目背景 mzc与djn第四弹. 题目描述 mzc家很有钱(开玩笑),他家有n个男家丁(做过前三弹的都知道).但如此之多的男家丁吸引来了我们的体委(矮胖小伙),他要来与mzc争夺男家丁. mzc很生气 ...
- redis分布式共享锁模拟抢单的实现
本篇内容主要讲解的是redis分布式锁,并结合模拟抢单的场景来使用,内容节点如下: jedis的nx生成锁 如何删除锁 模拟抢单动作 1.jedis的nx生成锁 对于分布式锁的生成通常需要注意如下几个 ...
- k sum(lintcode)
没通过的代码: class Solution { public: /* * @param A: An integer array * @param k: A positive integer (k & ...
- linux_1
注: 创建软连接: "ln -s xxx 路径1" 在路径1创建xxx的软连接 特点: 1.文件类型 l 2.相当于windows的快捷方式 创建硬链接: "ln xxx ...
- shell脚本,awk 根据文件某列去重并且统计该列频次。
a文件为 a a a s s d .怎么把a文件变为 a s d .怎么把a文件变为 a a a s s d 解题方法如下: 解题思路 [root@localhost study]# awk 'NR= ...
- 设置section的距离
在ios7中使用group类型的tableview时,第一个section距离navigationbar的距离很大,不符合这边的设计图.使用 myTableView . sectionHeaderHe ...
- 【Java_基础】Java中Native关键字的作用
本篇博文转载与:Java中Native关键字的作用
- 初遇Linux
Ctrl+Alt+(F1-F6):切换虚拟终端 Ctrl+Alt:鼠标切换界面 $:普通用户登录后系统的提示符 #:root用户登录后系统的提示符 Linux命令 exit 用于退出目前的shell ...