P4467 [SCOI2007]k短路
题目描述
有 n 个城市和 m 条单向道路,城市编号为 1 到 n 。每条道路连接两个不同的城市,且任意两条道路要么起点不同要么终点不同,因此 n 和 m 满足 m \le n(n-1)m≤n(n−1) 。
给定两个城市a
和b
,可以给a
到b
的所有简单路(所有城市最多经过一次,包括起点和终点)排序:先按长度从小到大排序,长度相同时按照字典序从小到大排序。你的任务是求出a
到b
的第 k 短路
输入输出格式
输入格式:
输入第一行包含五个正整数n, m, k, a, b。
以下m行每行三个整数u, v, l,表示从城市u到城市v有一条长度为l的单向道路。
输出格式:
如果a到b的简单路不足k条,输出No,否则输出第k短路:从城市a开始依次输出每个到达的城市,直到城市b,中间用减号"-"分割。
输入输出样例
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-2-4-3-5
4 6 1 1 4
2 4 2
1 3 2
1 2 1
1 4 3
2 3 1
3 4 1
1-2-3-4
3 3 5 1 3
1 2 1
2 3 1
1 3 1
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短路的更多相关文章
- BZOJ1073 [SCOI2007]kshort K短路,A*
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1073 题意概括 以距离为第一关键字,字典序为第二关键字,在所有的从S到T的路径中,选择不重复经过某 ...
- A* K短路
注:\(A*\) 求解K短路效率极其低下,时间复杂度\(O(nklog\ n)\),空间视题目而定,因为本质是爆搜,可求解数据范围较小的题目. 我们使用\(A*\)求解k短路: 首先需要预处理出估价函 ...
- POJ 2449 Remmarguts' Date --K短路
题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...
- POJ 2449Remmarguts' Date K短路模板 SPFA+A*
K短路模板,A*+SPFA求K短路.A*中h的求法为在反图中做SPFA,求出到T点的最短路,极为估价函数h(这里不再是估价,而是准确值),然后跑A*,从S点开始(此时为最短路),然后把与S点能达到的点 ...
- BZOJ-1975 魔法猪学院 K短路 (A*+SPFA)
1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1323 Solved: 433 [Submit][Statu ...
- 【POJ】2449 Remmarguts' Date(k短路)
http://poj.org/problem?id=2449 不会.. 百度学习.. 恩. k短路不难理解的. 结合了a_star的思想.每动一次进行一次估价,然后找最小的(此时的最短路)然后累计到k ...
- poj 2449 Remmarguts' Date K短路+A*
题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...
- 第k短路
poj 2449 模板题 A*+spfa #include<iostream> #include<cstdio> #include<cstring> #inclu ...
- poj 2449(A*求第K短路)
题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...
随机推荐
- JS高级. 02 面向对象、创建对象、构造函数、自定义构造函数、原型
面向对象的三大特性: 封装 a) 把一些属性和方法装到一个对象里 2. 继承 a) js中的继承是指: 一个对象没有一些方法和属性,而另一个对象有 把另一个个对象的属性和方法,拿过来自己用, ...
- Laravel -- 模型
模型文件 <?php namespace App; use Illuminate\Database\Eloquent\Model; class Student extends Model { / ...
- ABAP CDS ON HANA-(11)ABAP CDSでの関連付け
Association in ABAP CDS An association in CDS view joins different data sources. Defining and using ...
- Druid时序数据库升级流程
目前Druid集群版本为0.11.0,新版本0.12.1已支持Druid SQL和Redis,考虑到Druid新特性以及性能的提升,因此需要将Druid从0.11.0版本升级到0.12.1版本,下面将 ...
- 谈谈WPF中的CollectionView与CollectionViewSource (1)
原文:谈谈WPF中的CollectionView与CollectionViewSource (1) 谈谈WPF中的CollectionView与CollectionViewSource (1) ...
- AR技术介绍(Located in Android)
一,什么是AR 在说AR技术之前,先来说说VR. 虚拟现实(VR:Virtual Reality)是采用以计算机技术为核心的技术,生成逼真的视,听,触觉等一体化的虚拟环境,用户借助必要的设备以自然的方 ...
- Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. org/apache/hadoop/hbase/
Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. org/apache/hadoop/hbase/ ...
- 创龙DSP6748开发板SYS/BIOS的LED闪烁-第2篇
1. 作为1个456MHz的处理器,不跑个操作系统说不过去,直接打开工程\Demo\SYSBIOS\Application\GPIO_LED,主函数比较简单 // 创建任务 Task_create(t ...
- 不得不服!Python速度虽然慢,但是它工作效率很高!
写在前面 让我们来讨论一个我最近一直在思考的问题:Python 的性能.顺便说一下,我是 Python 的忠实拥趸,我在各种情况下都会积极尝试使用 Python 来解决问题.大家对 Python 最大 ...
- python终极篇 --- django---班级管理系统
周末没事自己写了个班级管理系统,虽然简单,但也算个前期学习的总结吧 from django.db import models # Create your models here. class Banj ...