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. upper_bound()和lower_bound()

    ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)算法返回一个非递减序列[first, la ...

  2. HDU 4405: Aeroplane chess

    类型:概率DP 题意:一条直线下飞行棋,色子六个面等概率.同时存在一些飞机航线,到了某个点可以直接飞到后面的另一个点,可以连飞,保证一个点至多一条航线.求到达或者超过终点 所需要 掷色子的期望次数. ...

  3. TStringList,快速解析 查找测试。。。很有用,再也不用 FOR 循环了

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABKAAAALHCAIAAAA2Gq0zAAAgAElEQVR4nOydeVgUV76wK5OZb5JJZi

  4. MinGW 使用和创建 DLL 应注意的问题

    MinGW 是 GCC 的 Windows 版本,稳定版已经到了 4.5.2,功能和性能上很好,感觉不比 Microsoft 自家的 VC 差啊.但是 MinGW 下使用和创建 DLL 倒是要特别注意 ...

  5. LeetCode OJ——Word Ladder2

    http://oj.leetcode.com/problems/word-ladder-ii/ class Solution { public: vector<vector<string& ...

  6. Codeforces 597B Restaurant(离散化 + 贪心)

    题目链接 Restaurant 题目意思就是在$n$个区间内选出尽可能多的区间,使得这些区间互不相交. 我们先对这$n$个区间去重. 假如有两个区间$[l1, r1],[l2, r2]$ 若满足$l1 ...

  7. Codeforces Round #439 (Div. 2) 题解

    题目链接  Round 439 div2 就做了两道题TAT 开场看C题就不会 然后想了好久才想到. 三种颜色挑出两种算方案数其实是独立的,于是就可以乘起来了. E题想了一会有了思路,然后YY出了一种 ...

  8. PV、PVC、StorageClass讲解

    PV.PVC.StorageClass讲解 为了方便开发人员更加容易的使用存储才出现的概念.通常我们在一个POD中定义使用存储是这样的方式,我们以hostpath类型来说: apiVersion: v ...

  9. 洛谷——P2701 [USACO5.3]巨大的牛棚Big Barn

    P2701 [USACO5.3]巨大的牛棚Big Barn 题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他 ...

  10. Wireshark如何选择多行

    Wireshark如何选择多行   在Wireshark中,用户经常需要选择几行,然后进行批量操作,如导出或者分析.但Wireshark没有提供通过鼠标直接选择多行的功能.这个时候,用户需要采用标记分 ...