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. saltstack实战4--综合练习4

    Saltstack配置管理-给minion增加Zabbix-agent zabbix-agent的包 [root@A ~]# rpm -qa |grep zabbix zabbix-2.4.8-1.e ...

  2. PHP面向对象:类型提示

    PHP是弱类型语言,向方法传递参数时候也不太区分类型.这样的使用会引起很多的问题,PHP开发者认为,这些问题应该是由代码书写者在书写代码时进行检验以避免. 没有类型提示很危险 下面的代码可能会出现问题 ...

  3. CSS常用中文字体、字号

    字体(font-family): 新细明体:PMingLiU 细明体:MingLiU 标楷体:DFKai-SB 黑体:SimHei 宋体:SimSun 新宋体:NSimSun 仿宋:FangSong  ...

  4. iOS安全——代码混淆&反编译

    本文是初步了解和集成网上的相关反编译博客, 并做公司内部技术人员分享研讨PPT.

  5. UINavigationController切换视图的简单使用

    UINavigationController通过栈的方式来管理视图,通过push将视图压入栈,pop将视图推出栈. 下面通过简单的示例说明 AppDelegate.m - (BOOL)applicat ...

  6. C#调用dll时的类型转换总结

    C++(Win 32) C# char** 作为输入参数转为char[],通过Encoding类对这个string[]进行编码后得到的一个char[] 作为输出参数转为byte[],通过Encodin ...

  7. 你早该这么玩Excel 读书笔记

    1. Excel用来分析数据,至少要有一份原始数据和对于的分类汇总数据,这两种数据在一项任务中,应该是存放在同一个Excel文档中的,在书籍中,把他们叫做源数据表和分类汇总表.用户输入源数据表,根据相 ...

  8. ecshop中无限处理分类

    数据库表记录结构 <?php $sql = "SELECT c.cat_id, c.cat_name, c.measure_unit, c.parent_id, c.is_show, ...

  9. 一款js点击显示和隐藏的例子(pc,移动端通用)

    html部分: <div id="box"> <div id="box_title">标题</div> <div id ...

  10. spark向量

    转自 1.本地向量MLlib的本地向量主要分为两种,DenseVector和SparseVector,顾名思义,前者是用来保存稠密向量,后者是用来保存稀疏向量,其创建方式主要有一下三种(三种方式均创建 ...