题目描述

“那是一条神奇的天路诶~,把第一个神犇送上天堂~”,XDM先生唱着这首“亲切”的歌曲,一道猥琐题目的灵感在脑中出现了。

和C_SUNSHINE大神商量后,这道猥琐的题目终于出现在本次试题上了,旨在难到一帮大脑不够灵活的OIer们(JOHNKRAM真的不是说你……)。

言归正传,小X的梦中,他在西藏开了一家大型旅游公司,现在,他要为西藏的各个景点设计一组铁路线。但是,小X发现,来旅游的游客都很挑剔,他们乘火车在各个景点间游览,景点的趣味当然是不用说啦,关键是路上。试想,若是乘火车一圈转悠,却发现回到了游玩过的某个景点,花了一大堆钱却在路上看不到好的风景,那是有多么的恼火啊。

所以,小X为所有的路径定义了两个值,Vi和Pi,分别表示火车线路的风景趣味度和乘坐一次的价格。现在小X想知道,乘客从任意一个景点开始坐火车走过的一条回路上所有的V之和与P之和的比值的最大值。以便为顾客们推荐一条环绕旅游路线(路线不一定包含所有的景点,但是不可以存在重复的火车路线)。

于是,小X梦醒之后找到了你……

输入输出格式

输入格式:

第一行两个正整数N,M,表示有N个景点,M条火车路线,火车路线是单向的。

以下M行,每行4个正整数,分别表示一条路线的起点,终点,V值和P值。

注意,两个顶点间可能有多条轨道,但一次只能走其中的一条。

输出格式:

一个实数,表示一条回路上最大的比值,保留1位小数。

若没有回路,输出-1。

输入输出样例

输入样例#1:

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

2.3

说明

对于30%的数据,1≤N≤100,1≤M≤20;

对于60%的数据,1≤N≤3,000,1≤M≤2,000;

对于100%的数据,1≤N≤7,000,1≤M≤20,000,1≤Vi,Pi≤1,000.

保证答案在200以内.

思路:01分数规划。

尽管加上了各种优化,还是只能拿80分。

#include<deque>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 50010
using namespace std;
int n,m,tot;
double l,r,mid;
double intrest[MAXN],cap[MAXN],dis[MAXN];
int to[MAXN],head[MAXN],net[MAXN],vis[MAXN],num[MAXN];
inline int read(){
char ch=getchar();int data=;
while(ch<''||ch>'') ch=getchar();
do{
data=data*+ch-'';
ch=getchar();
}while(ch>='' && ch<='');
return data;
}
inline void add(int u,int v,double w,double p){
to[++tot]=v;net[tot]=head[u];intrest[tot]=w;cap[tot]=p;head[u]=tot;
}
inline bool spfa(int s){
deque<int>que;
memset(vis,,sizeof(vis));
memset(num,,sizeof(num));
memset(dis,0x7f,sizeof(dis));
que.push_back(s);
dis[s]=;vis[s]=;num[s]++;
while(!que.empty()){
int now=que.front();
que.pop_front();
vis[now]=;
for(int i=head[now];i;i=net[i])
if(dis[to[i]]>dis[now]+mid*cap[i]-intrest[i]){
dis[to[i]]=dis[now]+mid*cap[i]-intrest[i];
if(!vis[to[i]]){
if(dis[to[i]]>dis[now]) que.push_back(to[i]);
else que.push_front(to[i]);
vis[to[i]]=;
num[to[i]]++;
if(num[to[i]]>n) return true;
}
}
}
return false;
}
inline bool check(double x){
if(spfa()) return true;
else return false;
}
int main(){
n=read();m=read();
for(int i=;i<=m;i++){
int x,y;double v,p;
x=read();y=read();
scanf("%lf%lf",&v,&p);
add(x,y,v,p);
}
for(int i=;i<=n;i++) add(,i,,);
l=;r=;
while(r-l>0.01){
mid=(l+r)/;
if(check(mid)) l=mid;
else r=mid;
}
if(l==) cout<<"-1";
else printf("%.1lf",r);
}

bfs的spfa判负环

dfs判负环AC    19ms

#include<deque>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 50010
using namespace std;
int n,m,tot;
double l,r,mid,ans;
double intrest[MAXN],cap[MAXN],dis[MAXN];
int to[MAXN],head[MAXN],net[MAXN],vis[MAXN];
inline void add(int u,int v,double w,double p){
to[++tot]=v;net[tot]=head[u];intrest[tot]=w;cap[tot]=p;head[u]=tot;
}
bool spfa(int now){
vis[now]=;
for(int i=head[now];i;i=net[i])
if(dis[to[i]]>dis[now]+mid*cap[i]-intrest[i]){
dis[to[i]]=dis[now]+mid*cap[i]-intrest[i];
if(vis[to[i]]||spfa(to[i])){
vis[to[i]]=;
return true;
}
}
vis[now]=;
return false;
}
inline bool check(double x){
for(int i=;i<=n;i++)
if(spfa(i)) return true;
return false;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
int x,y;double v,p;
scanf("%d%d",&x,&y);
scanf("%lf%lf",&v,&p);
add(x,y,v,p);
}
l=;r=;
while(r-l>0.01){
mid=(l+r)/;
if(check(mid)){
ans=mid;
l=mid;
}
else r=mid;
}
if(l==) cout<<"-1";
else printf("%.1lf",ans);
}

对比一下spfa的bfs判负环和dfs判负环的时间复杂度:

这些是bfs的尽管加上了各种优化还以一直TLE

而下面的:

  第一行是没加读入优化的dfs。

  第二行是加上读入优化的dfs。

dfs的速度秒杀bfs

浴谷 P1768 天路的更多相关文章

  1. 洛谷 P1768 天路

    P1768 天路 题目描述 “那是一条神奇的天路诶~,把第一个神犇送上天堂~”,XDM先生唱着这首“亲切”的歌曲,一道猥琐题目的灵感在脑中出现了. 和C_SUNSHINE大神商量后,这道猥琐的题目终于 ...

  2. 浴谷夏令营例题Codeforces827DBest Edge Weight(三个愿望,一次满足~(大雾

    这题在浴谷夏令营wyx在讲的最小生成树的时候提到过,但并没有细讲怎么写... 这题可以用三种写法写,虽然只有两种能过...(倍增/倍增+并查集/树链剖分 先跑出最小生成树,分类讨论,在MST上的边,考 ...

  3. [P1768]天路(分数规划+SPFA判负环)

    题目描述 “那是一条神奇的天路诶~,把第一个神犇送上天堂~”,XDM先生唱着这首“亲切”的歌曲,一道猥琐题目的灵感在脑中出现了. 和C_SUNSHINE大神商量后,这道猥琐的题目终于出现在本次试题上了 ...

  4. Luogu P1768 天路 0/1分数规划+dfs spfa

    “那是一条神奇的天路诶~~把第一个神犇送上天堂” 怕不是某大佬早就A了这题,然鹅我又调了很久很久... 好吧就是0/1分数规划,但是跑的dfs的spfa(好像题解说bfs过不了????不知) 发现把s ...

  5. 浴谷八连测R6题解(收获颇丰.jpg)

    这场的题都让我收获颇丰啊QWQ 感谢van♂老师 T1 喵喵喵!当时以为经典题只能那么做, 思维定势了... 因为DP本质是通过一些条件和答案互相递推的一个过程, 实际上就是把条件和答案分配在DP的状 ...

  6. 浴谷八连测R4题解

    一开始出了点bug能看见排行榜,于是我看见我半个小时就A掉了前两题,信心场QAQ T1字符串题就不说了qwq #include<iostream> #include<cstring& ...

  7. 洛谷10月月赛R2·浴谷八连测R3题解

    早上打一半就回家了... T1傻逼题不说了...而且我的写法比题解要傻逼很多T T T2可以发现,我们强制最大值所在的块是以左上为边界的倒三角,然后旋转4次就可以遍历所有的情况.所以二分极差,把最大值 ...

  8. 浴谷金秋线上集训营 T11738 伪神(树链剖分)

    先树链剖分,一棵子树的编号在数组上连续,一条链用树链剖分,把这些线段全部取出来,做差分,找到有多少点被>=t条线段覆盖即可. #include<iostream> #include& ...

  9. luogu P1768 天路

    嘟嘟嘟 01分数规划之最优比率环. 主要是发一下基于dfs的spfa.跑的贼快,原来总用时2000多ms还TLE了两个点,改成dfs后总用时直降43ms! #include<cstdio> ...

随机推荐

  1. js函数参数理解

    eg: function setName(obj){ obj.name = "Nicholas"; obj = new Object(); obj.name = "Gre ...

  2. RocketMQ学习笔记(3)----RocketMQ物理结构和逻辑部署结构

    1. RocketMQ的物理结构 RecketMQ网络部署的特点: Name Server是一个几乎无状态特点,可集群部署,节点之间无任何信息同步的(相对于zookeeper是较为轻量级的). Bro ...

  3. tomcat更改日志路径

    共有2个地方需要更改. 1.   tomcat/conf/logging.properties 步骤1--查找:grep logs logging.properties 步骤2--替换:sed -i ...

  4. Sublime Text编辑器配置Python解释器简易教程

    前天在微信上遇到一个小伙伴问我一个关于Sublime text配置Python解释器的问题,可能是初学者,对这方面还不是很懂,想使用快捷键但是徒劳一场,因为缺少Python解释器,直接按下快捷键Ctr ...

  5. vue下assets下的静态资源和static下的静态资源的区别

    区别一(最终位置) assets文件是src下的,所以最后运行是需要进行打包,而static文件不需要打包直接放在最终的文件中了 区别二(引用方式) assets中的文件在vue中的template/ ...

  6. [洛谷P3948]数据结构

    题目大意:有n个数,opt个操作,并给你md.min.max. 每种操作有以下两种:1.给一段区间加一个固定值.2.询问一段区间内满足$min\leq T*i\ mod\ md\leq max$(T是 ...

  7. py_One

    1.Python 标识符 在 Python 里,标识符由字母.数字.下划线组成. 在 Python 中,所有标识符可以包括英文.数字以及下划线(_),但不能以数字开头. Python 中的标识符是区分 ...

  8. OpenJDK源码研究笔记(一)-参数检查&抛出带关键错误提示信息的异常

    OpenJDK源码研究笔记系列文章,是我在阅读OpenJDK7源码的过程中的一些体会.收获.看法. 把研究过程中的成长和收获一点点地整理出来,是对自己研究学习的一个小结,也有可能给学习Java的一些同 ...

  9. Unity 制作安装程序和卸载程序

    1.最简单的方式通过winrar制作 但是做出来的页面好low的感觉 参考链接:https://www.cnblogs.com/fetty/p/5185913.html 2.通过inno制作安装程序: ...

  10. C语言中头文件尖括号和引号的区别

    用include 引用头文件时,双引号和尖括号的区别: 1.双引号:引用非标准库的头文件,编译器首先在程序源文件所在目录查找,如果未找到,则去系统默认目录查找,通常用于引用用户自定义的头文件. 2.尖 ...