【BZOJ-3627】路径规划 分层图 + Dijkstra + spfa
3627: [JLOI2014]路径规划
Time Limit: 30 Sec Memory Limit: 128 MB
Submit: 186 Solved: 70
[Submit][Status][Discuss]
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
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
HINT
共14组数据:
其中3组数据,满足n<10,m<20,k<5
另有3组没有红绿灯
所有数据满足n<=10000,m<=20000,k<=10,加油站<=50
答案保留3位小数
Source
Solution
这个题搞起来很劲啊....算法不是很难,但是写起来真是容易写残。
从数据范围和题意看出是分层图,但有两个限制条件,分别是红绿灯和加油站,但是一次分层并不能限制两个条件,所以只可能是先处理其中一个再考虑另一个。
所以先处理红绿灯,先对红绿灯搞一个分层图,每层表示经过这个层数个红绿灯的最短路,这样不考虑油量限制可以直接跑最短路得到。
但是之后还得处理油量,但是加油站数量比较少,可以跑多遍,求出每个加油站出发的最短路,这样就可以得到两个加油站是否可以一箱油到达;
可以一箱油到达就没什么好害怕的了,然后再枚举到另一个加油站经过多少个红绿灯的情况,建出另一个图;
这个图依旧是分层图,每层表示经过这个层数的红绿灯的可以直接到达的加油站之间的最短路,然后再在这个图上跑一遍最短路即可。
红灯的情况是需要求期望的,求法比较简单,答案就是$\frac {red^{2}}{2*(red+green)}$,这个价值可以直接付给出边,加油站的时候在最短路时加上Cost即可。
一开始写了两个Dij然后炸了,惊恐的换成了一个spfa,在跑对加油站点分层的图的时候,标号特别蛋疼...读入什么处理的也比较无脑,可以直接认为起点终点就是两个加油站,最后答案减掉一个额外的Cost即可。
Code
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<algorithm>
- #include<queue>
- #include<map>
- #include<string.h>
- using namespace std;
- inline int read()
- {
- int x=,f=; char ch=getchar();
- while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
- while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
- return x*f;
- }
- #define MAXN 10010
- int N,M,K,L,C,Gas[],gas,id[][],ID,S,T,pre[MAXN];
- struct Point{char name[],id;double Ave; bool re;}p[MAXN];
- double dist[][MAXN];
- struct Graph
- {
- struct EdgeNode{int next,to; double dis;} edge[MAXN*];
- int head[MAXN],cnt;
- inline void AddEdge(int u,int v,double w) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].dis=w;}
- inline void InsertEdge(int u,int v,double w) {AddEdge(u,v,w); AddEdge(v,u,w);}
- #define Pa pair<int,int>
- #define Make make_pair
- #define Di top().first
- #define Po top().second
- #define INF (1LL<<60)
- double dis[MAXN];
- inline void preDijsktra(int st)
- {
- priority_queue<Pa, vector<Pa> , greater<Pa> > q;
- bool visit[][MAXN]={};
- for (int i=; i<=K; i++) for (int j=; j<=N; j++) dist[i][j]=INF;
- q.push(Make(,st)); dist[][st]=; visit[][st]=;
- while (!q.empty())
- {
- int now=q.Po,D=q.Di; q.pop(); visit[D][now]=;
- for (int i=head[now]; i; i=edge[i].next)
- {
- int tmp=D+(p[edge[i].to].re?:);
- if (tmp<=K && dist[D][now]+edge[i].dis+p[edge[i].to].Ave<=L && dist[tmp][edge[i].to]>edge[i].dis+p[edge[i].to].Ave+dist[D][now])
- {
- dist[tmp][edge[i].to]=dist[D][now]+p[edge[i].to].Ave+edge[i].dis;
- if (!visit[tmp][edge[i].to]) q.push(Make(tmp,edge[i].to)),visit[tmp][edge[i].to]=;
- }
- }
- }
- }
- inline void spfa(int st)
- {
- queue<int>Q; bool visit[MAXN];
- for (int i=; i<=ID; i++) dis[i]=INF;
- Q.push(st); dis[st]=0.0; visit[st]=;
- while (!Q.empty())
- {
- int now=Q.front(); Q.pop(); visit[now]=;
- int lay=(now-)/gas,pos=now%gas; if (!pos) pos=gas;
- for (int j=; j+lay<=K; j++)
- for (int i=head[j*gas+pos],ppp; i; i=edge[i].next)
- {
- ppp=edge[i].to%gas,ppp=!ppp? gas:ppp;
- if (dis[(j+lay)*gas+ppp]>dis[now]+edge[i].dis+C)
- {
- dis[(j+lay)*gas+ppp]=dis[now]+edge[i].dis+C;
- if (!visit[(j+lay)*gas+ppp]) Q.push((j+lay)*gas+ppp),visit[(j+lay)*gas+ppp]=;
- }
- }
- }
- }
- } G1,G2;
- map<string,int>hash;
- int main()
- {
- freopen("pathplan.in","r",stdin);
- freopen("pathplan.out","w",stdout);
- N=read(),M=read(),K=read(),L=read(),C=read();
- for (int i=; i<=N; i++)
- {
- double re,gr;
- scanf("%s%lf%lf",p[i].name+,&re,&gr),p[i].id=i,hash[p[i].name+]=i;
- if (re>) p[i].re=,p[i].Ave=(re*re)/2.0/(re+gr);
- }
- for (int i=; i<=N; i++)
- {
- string s=p[i].name+;
- if (s=="start" || s=="end" || s.find("gas")!=string::npos) Gas[++gas]=hash[s],pre[hash[s]]=gas;
- if (s=="start") S=hash[s];
- if (s=="end") T=hash[s];
- }
- for (int i=; i<=M; i++)
- {
- char u[],v[],na[]; double di;
- scanf("%s%s%s%lf",u+,v+,na+,&di);
- G1.InsertEdge(hash[u+],hash[v+],di);
- }
- for (int i=; i<=K; i++)
- for (int j=; j<=gas; j++)
- id[i][j]=++ID;
- for (int i=; i<=gas; i++)
- {
- G1.preDijsktra(Gas[i]);
- for (int j=; j<=gas; j++)
- if (i!=j)
- for (int k=; k<=K; k++)
- if (dist[k][Gas[j]]<INF)
- G2.AddEdge(id[k][i],id[k][j],dist[k][Gas[j]]);
- }
- G2.spfa(id[][pre[S]]);
- double ans=INF;
- for (int i=; i<=K; i++) ans=min(ans,G2.dis[id[i][pre[T]]]);
- printf("%.3lf\n",ans-C);
- return ;
- }
【BZOJ-3627】路径规划 分层图 + Dijkstra + spfa的更多相关文章
- 【BZOJ3627】【JLOI2014】路径规划 分层图
意甲冠军:要查找.有门户网站:http://www.lydsy.com/JudgeOnline/problem.php? id=3627 注意:点的等待时长示意图为: 非常清晰了吧?没事,不清晰就不清 ...
- [USACO09FEB] Revamping Trails 【分层图+Dijkstra】
任意门:https://www.luogu.org/problemnew/show/P2939 Revamping Trails 题目描述 Farmer John dutifully checks o ...
- BZOJ 2763 飞行路线(分层图最短路)题解
题意:中文题意不解释... 思路:分层图最短路,我们再开一维用来表示当前用了多少次免费次数,dis[i][j]就表示到达i点用了j次免费的最短路,有点DP的感觉. 当个模板用 参考:分层图最短路 代码 ...
- bzoj 2763 [JLOI2011]飞行路线——分层图
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2763 分层图两种方法的练习. 1.把图分成k+1层,本层去上面一层的边免费.但空间时间都不算 ...
- bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级——分层图+dijkstra
Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i ...
- bzoj 2763: [JLOI2011]飞行路线 -- 分层图最短路
2763: [JLOI2011]飞行路线 Time Limit: 10 Sec Memory Limit: 128 MB Description Alice和Bob现在要乘飞机旅行,他们选择了一家相 ...
- HDU-3499Flight (分层图dijkstra)
一开始想的并查集(我一定是脑子坏掉了),晚上听学姐讲题才知道就是dijkstra两层: 题意:有一次机会能使一条边的权值变为原来的一半,询问从s到e的最短路. 将dis数组开成二维,第一维表示从源点到 ...
- bzoj 2763: [JLOI2011]飞行路线 分层图
题目链接 n个点m条路, 每条路有权值, 给出起点和终点, 求一条路使得权值最小.可以使路过的路中, k条路的权值忽略. 其实就是多一维, 具体看代码 #include<bits/stdc++ ...
- 机器人路径规划其一 Dijkstra Algorithm【附动态图源码】
首先要说明的是,机器人路径规划与轨迹规划属于两个不同的概念,一般而言,轨迹规划针对的对象为机器人末端坐标系或者某个关节的位置速度加速度在时域的规划,常用的方法为多项式样条插值,梯形轨迹等等,而路径规划 ...
随机推荐
- entityframework学习笔记--009-使用原生sql语句操作数据
1 使用原生SQL语句更新--Database.ExecuteSqlCommand 假设你有一张如图9-1所示的Payment数据库表. 图9-1 1.1 实体类型: public class Pay ...
- instanceof 运算符
java中的instanceof=======>二元运算符 用法: result = object instanceof class 参数: result 是boolean类型 object 是 ...
- 关于mysql字段时间类型timestamp默认值为当前时间问题
今天把应用部署到AWS上发现后台修改内容提交后程序报错,经过排查发现是更新数据的时候,有张数据表中的一个timestamp类型的字段默认值变成了"0000-00-00 00:00:00.00 ...
- IIS7 应用程序池自动回收关闭的解决方案
在ASP.NET Application中加入某个定时任务,那想必一定是用一个线程在不停地做定时计算,在自己的ASP.NET应用程序中加入了Quartz.NET框架 夜间或者网站在经过无访问阶段后,后 ...
- 移动端图片随手势移动react组件(附移动开发小tips)
这个效果是公司产品中一个用到的效果,用于展示项目的信息,废话少说,先上效果图,代码在最后:),这个组件是在上篇博客中用webpack搭建的环境中完成的http://www.cnblogs.com/wu ...
- android Fragments介绍
Fragments是Android3.0引入的概念,译为片段.碎片,为了解决不同屏幕分辩率的动态和灵活UI设计. Fragment表现Activity中UI的一个行为或者一部分.可以将多个fragme ...
- IT菜鸟的生存指南(三)流行还是经典
经常被刚入行的新人请教,想学一门开发语言,最好又简单工资又高又有发展前途.那门语言最好这个话题能在程序员群里吵一下午,所以我也就不掀起战争了. 个人建议如下: 工资高不高不在于学那门语言,而在于你的行 ...
- H5 表格标签的其它标签
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 读《乔布斯的NeXT和苹果之间,隔了这两个创业常识》
原文链接:http://wwww.huxiu.com/article/114950/1.html 前言: 当今硅谷风头最劲的风险投资家马克·安德森曾说,硅谷每年大约诞生15-20家真正值得投资的公司. ...
- JavaScript 事件
事件 概念:事件是可以被 JavaScript 侦测到的行为. JavaScript 使我们有能力创建动态页面.事件是可以被 JavaScript 侦测到的行为. 网页中的每个元素都可以产生某些可以触 ...