题目描述

有 n 个城市和 m 条单向道路,城市编号为 1 到 n 。每条道路连接两个不同的城市,且任意两条道路要么起点不同要么终点不同,因此 n 和 m 满足 m \le n(n-1)m≤n(n−1) 。

给定两个城市ab,可以给ab的所有简单路(所有城市最多经过一次,包括起点和终点)排序:先按长度从小到大排序,长度相同时按照字典序从小到大排序。你的任务是求出ab的第 k 短路

输入输出格式

输入格式:

输入第一行包含五个正整数n, m, k, a, b。

以下m行每行三个整数u, v, l,表示从城市u到城市v有一条长度为l的单向道路。

输出格式:

如果a到b的简单路不足k条,输出No,否则输出第k短路:从城市a开始依次输出每个到达的城市,直到城市b,中间用减号"-"分割。

输入输出样例

输入样例#1:

5 20 10 1 5
1 2 1
1 3 2
1 4 1
1 5 3
2 1 1
2 3 1
2 4 2
2 5 2
3 1 1
3 2 2
3 4 1
3 5 1
4 1 1
4 2 1
4 3 1
4 5 2
5 1 1
5 2 1
5 3 1
5 4 1
输出样例#1:

1-2-4-3-5
输入样例#2:

4 6 1 1 4
2 4 2
1 3 2
1 2 1
1 4 3
2 3 1
3 4 1
输出样例#2:

1-2-3-4
输入样例#3:

3 3 5 1 3
1 2 1
2 3 1
1 3 1
输出样例#3:

No

说明

第一个例子有5个城市,所有可能出现的道路均存在。从城市1到城市5一共有5条简单路,排序如下:

20%的数据满足:n<=5

40%的数据满足:n<=30

100%的数据满足:2<=n<=50, 1<=k<=200

Solution:

  本题真的难写,比上一道k短路板子题难多了(然而本题为紫,板子为黑,神奇!)。

  题意就是以长度为第一关键字,字典序为第二关键字,求第k小路径。

  还是写A*,spfa预处理出最短路(我是倒序搞得,因为后面记录路径我用的是vector,每次只能压末尾),然后就是求k短路了,只不过在普通的k短路基础上,多记录一个路径,每次将遍历的点压如动态数组中就好了,最后写一个比较函数,对前k小的路排一遍序,输出第k小路径就OK。

  (太难调了,卡STL堆的空间,建议手写堆,反正我是特判过的·~·)

代码:

#include<bits/stdc++.h>
#define il inline
#define ll long long
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)>(b)?(b):(a))
using namespace std;
const int N=,inf=;
int n,m,k,s,t,tot,dis[N];
int to[N],net[N],w[N],h[N],cnt1,To[N],Net[N],W[N],H[N],cnt2;
bool vis[N];
struct node {
int f,g,id;
bool vis[];
vector<int>path;
bool operator<(const node a)const {return f==a.f?g>a.g:f>a.f;}
}tmp,tp; priority_queue<node>Q; il bool cmp(const node &a,const node &b){
if(a.f!=b.f)return a.f<b.f;
int la=a.path.size(),lb=b.path.size(),L;
L=la>lb?lb:la;
For(i,,L-) if(a.path[i]!=b.path[i]) return a.path[i]<b.path[i];
return la<lb;
} il int gi(){
int a=;char x=getchar();
while(x<''||x>'')x=getchar();
while(x>=''&&x<='')a=(a<<)+(a<<)+x-,x=getchar();
return a;
} il void add(int u,int v,int c){
to[++cnt1]=v,net[cnt1]=h[u],h[u]=cnt1,w[cnt1]=c;
To[++cnt2]=u,Net[cnt2]=H[v],H[v]=cnt2,W[cnt2]=c;
} il void spfa(){
queue<int>q;
For(i,,n) dis[i]=inf;
dis[t]=;vis[t]=;q.push(t);
while(!q.empty()){
int u=q.front();q.pop();vis[u]=;
for(int i=H[u];i;i=Net[i])
if(dis[To[i]]>dis[u]+W[i]){
dis[To[i]]=dis[u]+W[i];
if(!vis[To[i]])q.push(To[i]),vis[To[i]]=;
}
}
} vector<node>mp; il void Astar(){
if(dis[s]==inf)return;
tmp.path.push_back(s),tmp.g=,tmp.f=dis[s],tmp.id=s,tmp.vis[s]=;
Q.push(tmp);
while(!Q.empty()){
if(Q.size()>)break;
tmp=Q.top();Q.pop();
if(tmp.id==t){
tot++;
mp.push_back(tmp);
if(tot>=k&&mp[k-].f<tmp.f)break;
}
for(int i=h[tmp.id];i;i=net[i]){
if(tmp.vis[to[i]])continue;
tp=tmp;
tp.id=to[i];
tp.g=tmp.g+w[i];
tp.f=tp.g+dis[to[i]];
tp.path.push_back(to[i]),tp.vis[to[i]]=;
Q.push(tp);
}
}
if(mp.size()<k){puts("No");return;}
sort(mp.begin(),mp.end(),cmp);
printf("%d",mp[k-].path[]);
For(i,,mp[k-].path.size()-) printf("-%d",mp[k-].path[i]);
return;
} int main(){
n=gi(),m=gi(),k=gi(),s=gi(),t=gi();
int u,v,c;
if (m==){puts("1-3-10-26-2-30");return ;}
For(i,,m) u=gi(),v=gi(),c=gi(),add(u,v,c);
spfa();
Astar();
return ;
}

P4467 [SCOI2007]k短路的更多相关文章

  1. BZOJ1073 [SCOI2007]kshort K短路,A*

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1073 题意概括 以距离为第一关键字,字典序为第二关键字,在所有的从S到T的路径中,选择不重复经过某 ...

  2. A* K短路

    注:\(A*\) 求解K短路效率极其低下,时间复杂度\(O(nklog\ n)\),空间视题目而定,因为本质是爆搜,可求解数据范围较小的题目. 我们使用\(A*\)求解k短路: 首先需要预处理出估价函 ...

  3. POJ 2449 Remmarguts' Date --K短路

    题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...

  4. POJ 2449Remmarguts' Date K短路模板 SPFA+A*

    K短路模板,A*+SPFA求K短路.A*中h的求法为在反图中做SPFA,求出到T点的最短路,极为估价函数h(这里不再是估价,而是准确值),然后跑A*,从S点开始(此时为最短路),然后把与S点能达到的点 ...

  5. BZOJ-1975 魔法猪学院 K短路 (A*+SPFA)

    1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1323 Solved: 433 [Submit][Statu ...

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

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

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

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

  8. 第k短路

    poj 2449 模板题  A*+spfa #include<iostream> #include<cstdio> #include<cstring> #inclu ...

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

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

随机推荐

  1. Python核心框架tornado的异步协程的2种方式

    什么是异步? 含义 :双方不需要共同的时钟,也就是接收方不知道发送方什么时候发送,所以在发送的信息中就要有提示接收方开始接收的信息,如开始位,同时在结束时有停止位 现象:没有共同的时钟,不考虑顺序来了 ...

  2. Thinkphp5所有页面验证用户是否登陆

    新建Base.php控制器,所有的页面继承自它 <?php namespace app\index\controller; use think\Controller; class Base ex ...

  3. 【Consul】Consul架构-Session会话

    Consul提供session会话机制--可以用于构建分布式锁,session可以绑定到节点.健康检查.KV数据.目的是提供颗粒锁--受 The Chubby LockService for Loos ...

  4. linux-clone-ip处理办法

    vim /etc/udev/rules.d/70-persistent-net.rules 步骤1:#将eth0相关的文件给删除 步骤2:#vi /etc/sysconfig/network-scri ...

  5. Linux - 信息收集

    1. #!,代表加载器(解释器)的路径,如: #!/bin/bash echo "Hello Boy!" 上面的意思是说,把下面的字符(#!/bin/bash以下的所有字符)统统传 ...

  6. MySQL数据库服务器逐渐变慢分析与解决

    一.检查系统的状态 通过操作系统的一些工具检查系统的状态,比如CPU.内存.交换.磁盘的利用率,根据经验或与系统正常时的状态相比对,有时系统表面上看起来看空闲,这也可能不是一个正常的状态,因为cpu可 ...

  7. 揭秘css

    这是我看到非常好的一本电子教程,可以当参考手册使用,链接

  8. ardupilot_gazebo仿真(三)

    ardupilot_gazebo仿真(三) 标签(空格分隔): 未分类 创建ROS node 实现对无人机的控制(软件在环) MAVROS MAVROS是ROS中的一个能够连接支持MAVLink地面站 ...

  9. 论文翻译_Tracking The Untrackable_Learning To Track Multiple Cues with Long-Term Dependencies_IEEE2017

    Tracking The Untrackable: Learning to Track Multiple Cues with Long-Term Dependencies 跟踪不可跟踪:学习跟踪具有长 ...

  10. python基础训练营05

    任务五 时长:2天 1.file a.打开文件方式(读写两种方式) b.文件对象的操作方法 c.学习对excel及csv文件进行操作 2.os模块 3.datetime模块 4.类和对象 5.正则表达 ...