POJ 2449-Remmarguts' Date(A*+spfa)
2016-03-11 23:20
393 查看
Remmarguts' Date
Description
"Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, he told them a story.
"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
The first line contains two integer numbers N and M (1 <= N <= 1000, 0 <= M <= 100000). Stations are numbered from 1 to N. Each of the following M lines contains three integer numbers A, B and T (1 <= A, B <= N, 1 <= T <= 100). It shows that there is a directed
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
A single line consisting of a single integer number: the length (time required) to welcome Princess Uyuw using the K-th shortest path. If K-th shortest path does not exist, you should output "-1" (without quotes) instead.
Sample Input
Sample Output
Source
POJ Monthly,Zeyuan Zhu
题意:
给你n个点,m条路。然后再给你起点s,终点t,求k短路。而且题目要求s==t时中间也要有点,不能只是起点与终点。
第一次学习A*算法,遇到了许多问题,spfa不会,那个前向星弄了好久才明白。解决了spfa之后,Astar函数很快就看明白了。其实A*有点像是反向的spfa吧,不过它是要每次都是从路径最小的去拓展的,感觉像是恶心的暴力每个点然后再存起来,而速度能这麽快完全是优先队列的功劳,那个f = g+v;其实就是贪心的表达式啊。
AC代码:
Time Limit: 4000MS | Memory Limit: 65536K | |
Total Submissions: 25391 | Accepted: 6930 |
"Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, he told them a story.
"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
The first line contains two integer numbers N and M (1 <= N <= 1000, 0 <= M <= 100000). Stations are numbered from 1 to N. Each of the following M lines contains three integer numbers A, B and T (1 <= A, B <= N, 1 <= T <= 100). It shows that there is a directed
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
A single line consisting of a single integer number: the length (time required) to welcome Princess Uyuw using the K-th shortest path. If K-th shortest path does not exist, you should output "-1" (without quotes) instead.
Sample Input
2 2 1 2 5 2 1 4 1 2 2
Sample Output
14
Source
POJ Monthly,Zeyuan Zhu
题意:
给你n个点,m条路。然后再给你起点s,终点t,求k短路。而且题目要求s==t时中间也要有点,不能只是起点与终点。
第一次学习A*算法,遇到了许多问题,spfa不会,那个前向星弄了好久才明白。解决了spfa之后,Astar函数很快就看明白了。其实A*有点像是反向的spfa吧,不过它是要每次都是从路径最小的去拓展的,感觉像是恶心的暴力每个点然后再存起来,而速度能这麽快完全是优先队列的功劳,那个f = g+v;其实就是贪心的表达式啊。
AC代码:
#include<iostream> #include<functional> #include<algorithm> #include<cstring> #include<string> #include<vector> #include<cstdio> #include<queue> #include<cmath> #include<map> using namespace std; #define CRL(a) memset(a,0,sizeof(a)) #define QWQ ios::sync_with_stdio(0) #define inf 0x3f3f3f3f typedef unsigned long long LL; typedef long long ll; const int T = 200000+50; const int mod = 1000000007; int n,m,c,s,e,k; struct node { int v,next,w;//尾端点,相同头端点的上一条边存在的数组号,尾端点的权值 }e1[T],e2[T];//正向与反向存数据 struct Node { int f,g,v;//f代表f函数,g代表g函数,v代表当前所在的点 bool operator<(const Node& b)const{ return f>b.f||(f==b.f&&g>b.g); } }; int head[T],tail[T];//前向星辅助数组1,辅助数组2 int dis[1000+50];//节点的值 bool vis[1000+50];//标记数组 void Init()//初始化数组 { c = 0; fill(head,head+T,-1); fill(tail,tail+T,-1); } void add(int x,int y,int w)//前向星存储 { e1[c].v = y,e1[c].w = w; e1[c].next = head[x]; head[x] = c; e2[c].v = x,e2[c].w = w; e2[c].next = tail[y]; tail[y] = c++; } void spfa()//最短路 { fill(dis,dis+1050,inf); fill(vis,vis+1050,false); queue<int> q; q.push(e);//开始松弛点 dis[e] = 0; while(!q.empty()) { int u = q.front();q.pop(); vis[u] = 0; /*重新赋值为0,因为其它点也有可能要用到这个点,但用了这个点的就不会再用这个点 因为要是最短的路程,重复用一个点是不能有最短的路径的。 */ for(int i=tail[u];~i;i=e2[i].next){//搜索相同起点的所有不同终点的值 int v = e2[i].v; int w = e2[i].w; if(dis[v]>dis[u]+w){//如果起点+i这个点是比现在的起点小,更新 dis[v] = dis[u]+w; if(!vis[v]){//没标记就要标记且记录下这个点然后继续松弛 q.push(v); vis[v] = 1; } } } } } int Astar()//A* { int cnt = 0;//记录第几短 priority_queue<Node> Q; if(s==e)k++;//题目要求必须要走过路径,不能呆在原地就是终点 if(dis[s]==inf)return -1;//s不可达直接退出 Node t,tt; t.v = s,t.g = 0,t.f = t.g + dis[s]; //当前点的值,估价函数值,总的值 Q.push(t); while(!Q.empty()) { tt = Q.top(),Q.pop(); if(tt.v==e){//第cnt次找到终点,肯定在前面找的数越小(优先队列) cnt ++; if(cnt==k)return tt.g; } //以点s为起点的数都拓展一次 for(int i=head[tt.v];~i;i=e1[i].next){ t.v = e1[i].v; t.g = tt.g + e1[i].w;//反向值 t.f = t.g + dis[t.v];//总的权值 Q.push(t); } } return -1; } int main() { #ifdef zsc freopen("input.txt","r",stdin); #endif int i,j; while(~scanf("%d%d",&n,&m)) { int u,v,w; Init(); for(i=1;i<=m;++i){ scanf("%d%d%d",&u,&v,&w); add(u,v,w); } scanf("%d%d%d",&s,&e,&k); spfa(); printf("%d\n",Astar()); } return 0; }
相关文章推荐
- A星算法理解
- cocos2dx下的A星算法
- A星算法,找寻最短路径
- A*寻路算法入门(一)
- A*寻路算法(曼哈顿距离)
- Cocos2d-x 3.1.1 学习日志16--A星算法(A*搜寻算法)的学习
- 再译《A *路径搜索入门》之六
- A星算法简单机器人积木动作序列问题
- A*算法入门
- C语言-手把手教你写贪吃蛇AI(中)
- A*算法的原理
- A*(A星)算法学习资料
- A*带你踏上快车道
- POJ 1077-Eight(BFS+优先队列)
- POJ 3255-Roadblocks(A*+spfa)
- A* 寻路
- 基于A*算法10*10迷宫
- HDU 6181 Two Paths 次短路
- 江中游A星算法 第1课 预估移动消耗计算法则
- cocos2dx之寻路 A星