http://poj.org/problem?id=2449

Remmarguts' Date
Time Limit: 4000MS   Memory Limit: 65536K
Total Submissions: 18168   Accepted: 4984

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

2 2
1 2 5
2 1 4
1 2 2

Sample Output

14

Source

POJ Monthly,Zeyuan Zhu
 
【题解】:

给定一个图,求起点到终点的第k短路。

分析:先用dijkstra从t反向寻找最短路。然后使用A*算法,把f(i)=g(i) + h(i)。h(i)就是i点到t的最短距离。当某点出队次数达到k次的时候,结果为该点的当前路程+该点到t的最短距离。(我没有判断不连通的情况)

为什么这样做是对的呢?我们这样来思考,如果不实用最短路,而只使用A*那么t第x次出队的结果即为第x短路的距离。继而可以想到,从第一个出队次数达到x的点,沿着最短路走到t,一定是第x短路。

说实话我也没有完全理解。

另外注意s==t的情况,据说k要++,不明白为啥。

这个题用来测第k短路的模板真的再好不过了,累计我wa在这么几个地方:
1.起点和终点是同一点时一定要走,不能输出0;
2.用普通邻接矩阵的话要注意重边的问题(所以强烈推荐邻接表水所有题);

【code】:

 /**
Judge Status:Accepted Memory:9252K
Time:204MS Language:G++
Code Length:2590B Author:cj
*/ #include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<string.h> #define N 1005
#define M 200100
#define INF 1000000000
using namespace std; struct Edge
{
int v,next,c;
}edge[M]; struct Nod //A*中的优先队列数据类型
{
int v,d,h;
}; struct Dj //dijkstra中的优先队列数据类型
{
int u,dis;
}; bool operator < (Dj a,Dj b) //dijkstra中的优先对队重载<号
{
return b.dis<a.dis;
} bool operator < (Nod a,Nod b) //A*中的优先队列重载<号
{
return b.h+b.d<a.h+a.d;
} int head[N];
int tail[N];
int dis[N];
int visit[N];
int edge_cnt;
int cnt[N]; void init() //初始化
{
memset(head,-,sizeof(head));
memset(tail,-,sizeof(tail));
edge_cnt = ;
memset(visit,,sizeof(visit));
memset(cnt,,sizeof(cnt));
} void addEdge(int a,int b,int c)
{
edge[edge_cnt].v = b;
edge[edge_cnt].c = c;
edge[edge_cnt].next = head[a];
head[a] = edge_cnt++; //记录起始边 edge[edge_cnt].v = a;
edge[edge_cnt].c = c;
edge[edge_cnt].next = tail[b];
tail[b] = edge_cnt++; //记录结束边
}
void Dijkstra(int n,int t) //对于以各点为起点到t点的最短路径
{
priority_queue<Dj> p_q;
Dj now,temp;
int i;
for(i=;i<=n;i++) dis[i]=INF;
dis[t] = ;
temp.dis = ;
temp.u = t;
p_q.push(temp);
while(!p_q.empty())
{
temp = p_q.top();
p_q.pop();
if(visit[temp.u]) continue;
visit[temp.u] = ;
for(i=tail[temp.u];i!=-;i=edge[i].next)
{
int v = edge[i].v;
if(dis[v]>dis[temp.u]+edge[i].c)
{
dis[v]=dis[temp.u]+edge[i].c;
now.u = v;
now.dis = dis[v];
p_q.push(now);
}
}
}
} int Astar_Kth(int s,int t,int k)
{
Nod cur,nxt;
priority_queue<Nod> p_q;
cur.v = s;
cur.d = ;
cur.h = dis[s];
p_q.push(cur);
while(!p_q.empty())
{
cur = p_q.top();
p_q.pop();
cnt[cur.v]++;
if(cnt[cur.v]>k) continue;
if(cnt[t]==k) return cur.d;
int i;
for(i=head[cur.v];i!=-;i=edge[i].next)
{
int v = edge[i].v;
nxt.d = cur.d + edge[i].c;
nxt.v = v;
nxt.h = dis[v];
p_q.push(nxt);
}
}
return -;
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
int i;
int a,b,c;
init();
for(i=;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
addEdge(a,b,c);
}
int s,t,k;
scanf("%d%d%d",&s,&t,&k);
if(s==t) k++;
Dijkstra(n,t);
printf("%d\n",Astar_Kth(s,t,k));
return ;
}

poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)的更多相关文章

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

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

  2. POJ 2449 - Remmarguts' Date - [第k短路模板题][优先队列BFS]

    题目链接:http://poj.org/problem?id=2449 Time Limit: 4000MS Memory Limit: 65536K Description "Good m ...

  3. poj 2449 Remmarguts' Date 第k短路 (最短路变形)

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 33606   Accepted: 9116 ...

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

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

  5. POJ 2449 Remmarguts' Date ( 第 k 短路 && A*算法 )

    题意 : 给出一个有向图.求起点 s 到终点 t 的第 k 短路.不存在则输出 -1 #include<stdio.h> #include<string.h> #include ...

  6. 【POJ】2449 Remmarguts' Date(k短路)

    http://poj.org/problem?id=2449 不会.. 百度学习.. 恩. k短路不难理解的. 结合了a_star的思想.每动一次进行一次估价,然后找最小的(此时的最短路)然后累计到k ...

  7. 【POJ】2449.Remmarguts' Date(K短路 n log n + k log k + m算法,非A*,论文算法)

    题解 (搬运一个原来博客的论文题) 抱着板题的心情去,结果有大坑 就是S == T的时候也一定要走,++K 我发现按照论文写得\(O(n \log n + m + k \ log k)\)算法没有玄学 ...

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

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

  9. 图论(A*算法,K短路) :POJ 2449 Remmarguts' Date

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 ...

随机推荐

  1. poj 3164 最小树形图

    思路:就是裸的最小树形图~ #include<iostream> #include<cstdio> #include<cstring> #include<cm ...

  2. Oracle导入SQL脚本执行 scott 用户下的表删除了

    执行 .sql 文件时,应在 sqlplus  或 cmd 中执行,速度比plsql 中的command window 中书许多, scott 用户下的表删除了 可以执行如下 @D:\app\Admi ...

  3. MyBatis(3.2.3) - One-to-one mapping using nested ResultMap

    We can get Student along with the Address details using a nested ResultMap as follows: <resultMap ...

  4. android之回调函数的意义

    本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273) 看完这篇文后大家可以看看这个http://blog. ...

  5. Android第三方授权(QQ篇)

    QQ授权比微信授权相对来说会方便一些 同样需要去官网下载sdk和导入sdk到自己的工程 http://wiki.connect.qq.com/%E7%A7%BB%E5%8A%A8%E5%BA%94%E ...

  6. 北大ACM(POJ1004-Financial Management)

    Question:http://poj.org/problem?id=1004问题点:求平均值及格式化输出. Memory: 248K Time: 0MS Language: C++ Result: ...

  7. boost库区间range基本原理及使用实例

    由 www.169it.com 搜集整理 区间的概念类似于STL中的容器概念.一个区间提供了可以访问半开放区间[first,one_past_last)中元素的迭代器,还提供了区间中的元素数量的信息. ...

  8. javascript 中的 call

    Javascript中call的使用 Javascript中call的使用自己感觉蛮纠结的,根据文档很好理解,其实很难确定你是否真正的理解. call 方法应用于:Function 对象调用一个对象的 ...

  9. 3月3日(3) Binary Tree Preorder Traversal

    原题 Binary Tree Preorder Traversal 没什么好说的... 二叉树的前序遍历,当然如果我一样忘记了什么是前序遍历的..  啊啊.. 总之,前序.中序.后序,是按照根的位置来 ...

  10. Qt5中使用lambda表达式

    c11新特性中加入了lambda表达式,所以Qt 也支持 需在.pro文件中加入 CONFIG += c++11 例子: QString program = "C:/Windows/Syst ...