BZOJ3627: [JLOI2014]路径规划

Description

相信大家都用过地图上的路径规划功能,只要输入起点终点就能找出一条最优路线。现在告诉你一张地图的信息,请你找出最优路径(即最短路径)。考虑到实际情况,一辆车加满油能开的时间有限,所以在地图上增加了几个加油站。

地图由点和双向边构成,每个点代表一个路口,也有可能是加油站或起点终点。有些路口还装有红绿灯。由于经过太多的红绿灯会让人感到不爽,所以请求在经过不超过k个红绿灯的情况下,最少平均花费多少时间能从起点到终点。保证起点终点和加油站没有红绿灯。

(题目不考虑最坏情况下能否加到油,只考虑平均花费时间的前提下,车能否到达加油站加油)。

Input

第一行输入5个整数n,m,k,limit,cost,表示有n个点m条边,车能开limit长的时间,及加油所花时间cost。

接下来n行输入每个点信息,包括点的名称(带“gas”的为加油站,“start”为起点,“end”为终点),及该点是否有红绿灯,(a,b表示)(若为a=0则表示没有,a表示红灯长,b表示绿灯长)。

接下来m行输入每条边信息,包括边的起点,终点,边的名称,通过该边所花时长。

保证点和边名的长度不大于20,只有大小写字母,数字及‘_’组成。

Output

一行输出最少平均花费时长。

Sample Input

5 8 1 100 10
start 0 0
azhan 10 10
xxgasxx 0 5
bpoint 20 5
end 0 100
start azhan sdf 30
azhan xxgasxx ewfg 20
start end r3tg 200
end azhan 1xq2 70
azhan bpoint gg 10
xxgasxx bpoint kk 30
bpoint end dsg 40
xxgasxx end t_s 100

Sample Output

162.500

HINT

共14组数据:

其中3组数据,满足n<10,m<20,k<5

另有3组没有红绿灯

所有数据满足n<=10000,m<=20000,k<=10,加油站<=50

答案保留3位小数


题解Here!

题目大意:

给定一个无向图,每条边有边权,有些点有点权,一些点是加油站。

求一条起点到终点的最短路,使经过有点权的点不超过$k$次,一管油只能走$limit$的时间,时间到了就只能到加油站花$cost$的时间加油。

解法:

那个红绿灯的计算公式是$\frac{red^2}{2\times(red+green)}$。

然后把这个时间附加到节点的出边上。

然后,我们建立分层图:

第$i$层表示经过了$i$个红绿灯时,从源点到该点的最短路径长度。

如果没有油量限制,那么我们直接跑最短路就行了。

所以我们考虑如何去掉这个油量限制。

注意到加油站很少,于是我们枚举以每个加油站为起点,向其他加油站经过若干个红绿灯的最短路径。

若此长度不大于最大油量,那么可以直接转移。

我们用这种方法构造新图,依旧是分层图,可是每一层仅有$50$个点,且没有油量限制。

然后就能跑分层图$SPFA$了。

注:不知道为什么,我的$SPFA$要加上$SLF$优化才能过,否则就是#4 $TLE$。

附代码:(我自己都觉得好丑啊。。。)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<map>
#include<string>
#include<deque>
#include<cmath>
#define MAXN 10010
#define MAXM 200010
#define eps (1e-7)
#define MAX (1<<30)
using namespace std;
map<string,int> name;
int n,m,k,cost,limit,s,t;
int top=0,gas_stack[MAXN],id[MAXN][12];
double length[MAXN];
bool gas[MAXN];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
struct SPFA{
int c,head[MAXM];
double path[MAXM];
bool vis[MAXM];
SPFA(){c=1;}
struct Graph{
int next,to;
double w;
}a[MAXM<<2];
inline int relax(int u,int v,double w){
if(path[v]>path[u]+w){
path[v]=path[u]+w;
return 1;
}
return 0;
}
inline void add(int u,int v,double w){
a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++;
}
void spfa(int s){
int u,v;
deque<int> q;
for(int i=1;i<=n*(k+1);i++){path[i]=MAX;vis[i]=false;}
path[s]=0;
vis[s]=true;
q.push_back(s);
while(!q.empty()){
u=q.front();
q.pop_front();
vis[u]=false;
for(int i=head[u];i;i=a[i].next){
v=a[i].to;
if(relax(u,v,a[i].w)&&!vis[v]){
vis[v]=true;
if(!q.empty()){
if(path[v]>path[q.front()])q.push_back(v);
else q.push_front(v);
}
else q.push_back(v);
}
}
}
}
}one,two;
inline void add_edge(int u,int v,int w){
if(fabs(length[v])>eps)for(int j=0;j<k;j++)one.add(id[u][j],id[v][j+1],w+length[v]);
else for(int j=0;j<=k;j++)one.add(id[u][j],id[v][j],w);
}
void work(){
double ans=MAX;
two.spfa(s);
for(int i=0;i<=k;i++)ans=min(ans,two.path[t+i*n]);
printf("%.3lf\n",ans);
}
void init(){
string x;
int u,v;
double w;
n=read();m=read();k=read();limit=read();cost=read();
for(int i=0;i<=k;i++)
for(int j=1;j<=n;j++)
id[j][i]=j+i*n;
for(int i=1;i<=n;i++){
cin>>x;
name[x]=i;
int red=read(),green=read();
if(x=="start")s=i;
else if(x=="end")t=i;
if(x.find("gas")!=string::npos)gas[i]=true;
if(red)length[i]=1.00*red*red/(double)(2.00*(red+green));
else length[i]=0;
}
for(int i=1;i<=m;i++){
cin>>x;u=name[x];
cin>>x;v=name[x];
cin>>x;w=read();
add_edge(u,v,w);
add_edge(v,u,w);
}
gas[s]=gas[t]=true;
for(int i=1;i<=n;i++)if(gas[i])gas_stack[++top]=i;
for(int i=1;i<=top;i++){
one.spfa(gas_stack[i]);
for(int j=1;j<=top;j++){
if(i==j)continue;
w=(gas_stack[j]!=s&&gas_stack[j]!=t)?cost:0;
for(int l=0;l<=k;l++)
if(one.path[id[gas_stack[j]][l]]<=limit)
for(int p=0;p+l<=k;p++)
two.add(id[gas_stack[i]][p],id[gas_stack[j]][p+l],one.path[id[gas_stack[j]][l]]+w);
}
}
}
int main(){
init();
work();
return 0;
}

BZOJ3627: [JLOI2014]路径规划的更多相关文章

  1. 【BZOJ-3627】路径规划 分层图 + Dijkstra + spfa

    3627: [JLOI2014]路径规划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 186  Solved: 70[Submit][Status] ...

  2. 基于谷歌地图的Dijkstra算法水路路径规划

    最终效果图如下: 还是图.邻接表,可以模拟出几个对象=>节点.边.路径.三个类分别如下: Node 节点: using System; using System.Collections.Gene ...

  3. Unity路径规划

    Unity路径规划  转自:http://www.cnblogs.com/zsb517/p/4090629.html 背景 酷跑游戏中涉及到弯道.不规则道路. 找来一些酷跑游戏的案例来看,很多都是只有 ...

  4. iOS百度地图路径规划和POI检索详细总结-b

    路径规划.png 百度地图的使用 百度地图API的导入网上说了许多坑,不过我遇到的比较少,这里就放两个比较常见的吧.坑一: 奥联WIFI_xcodeproj.png 如上图所示,在infoplist里 ...

  5. COJ 0500 杨老师的路径规划(MST)最小生成树

    杨老师的路径规划(MST) 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 为满足同学们需求,杨老师在实验楼4层新建了好多个计算 ...

  6. octomap中3d-rrt路径规划

    路径规划 碰撞冲突检测 在octomap中制定起止点,目标点,使用rrt规划一条路径出来,没有运动学,动力学的限制,只要能避开障碍物. 效果如下: #include "ros/ros.h&q ...

  7. ROS(indigo)RRT路径规划

    源码地址:https://github.com/nalin1096/path_planning 路径规划 使用ROS实现了基于RRT路径规划算法. 发行版 - indigo 算法在有一个障碍的环境找到 ...

  8. ROS探索总结(十四)——move_base(路径规划)

    在上一篇的博客中,我们一起学习了ROS定位于导航的总体框架,这一篇我们主要研究其中最重要的move_base包. 在总体框架图中可以看到,move_base提供了ROS导航的配置.运行.交互接口,它主 ...

  9. 游戏AI之路径规划(3)

    目录 使用路径点(Way Point)作为节点 洪水填充算法创建路径点 使用导航网(Navigation Mesh)作为节点 区域分割 预计算 路径查询表 路径成本查询表 寻路的改进 平均帧运算 路径 ...

随机推荐

  1. 标准C程序设计七---57

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  2. select、poll和epoll的区别(转载)

    select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.但select ...

  3. Linux 之 Vim常用命令

    Vim常用命令 参考教程:[千峰教育] 终端编辑命令工具: vi/vim.emacs等. vim简介: vim是vi的扩展,被誉为终端编辑之神. vim安装: yum install -y vim 工 ...

  4. cmd 命令提示符常用操作

    切换盘符: d: 进入子目录: cd web 返回上级目录: cd .. 查询子目录下所有文件:dir

  5. 在路上:安全公司“跨界”SD-WAN

    编者按:本文是SDNLAB“企业+”特别报道之一.“企业+”是SDNLAB重点打造的栏目,汇聚信息行业运营商.设备商.互联网公司.软件公司.集成公司.融创投资公司.科研院所等企业,重新定义IT行业撮合 ...

  6. IDEA查看源码时提示:Library source does not match the bytecode for class的问题分析

    通过Maven查看依赖的源码时,通常是Maven自动下载JAR包附属的source包,但是会出现一个问题,由于使用lombok插件会造成编写的Java文件和编译后的class上有差别,所以IDEA打开 ...

  7. Xcode搭建真机调试环境 图文实例

    本文介绍的Xcode搭建真机调试环境 图文实例,图文并茂,使我们学习起来更方便些,我们先来看内容. AD: 2013云计算架构师峰会超低价抢票中 Xcode搭建真机调试环境 是本文要介绍的内容,不多说 ...

  8. 3.环境搭建-Hadoop(CDH)集群搭建

    目录 目录 实验环境 安装 Hadoop 配置文件 在另外两台虚拟机上搭建hadoop 启动hdfs集群 启动yarn集群 本文主要是在上节CentOS集群基础上搭建Hadoop集群. 实验环境 Ha ...

  9. 使用 sftp 向linux服务器传输文件

    sftp是加密的文件传输. 登陆 sftp name@123.21.331.1 1 2.把本地文件name1传到服务器name2下 put /name1.html /name2/ 1 把服务器name ...

  10. 关于小程序navigator没有高的情况

    传统的web开发者进入小程序的时候,可能有几个映射疑问: div  - > view a -> navigator携带参数传值(a标签应该是根据内容来撑高,而navigator就不会根据内 ...