题目描述

“那是一条神奇的天路诶~,把第一个神犇送上天堂~”,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. 【记录】Linux安装JDK详细步骤

    Linux安装JDK步骤1. 先从网上下载jdk(jdk-1_5_0_02-linux-i586.rpm) ,推荐SUN的官方网站www.sun.com,下载后放在/home目录中,当然其它地方也行. ...

  2. PIC18F26K20

    Clock Four Crystal modes, Two External clock modes,  Two RC Oscillator, Internal oscillator, PLL

  3. Python 曲线拟合

    #曲线拟合 fig = plt.figure() ax = fig.add_subplot(111)#将画布分割成1行1列,图像画在从左到右从上到下的第1块 ax.plot(Num,a,label=u ...

  4. .startsWith和endsWith的使用方法与说明

    a.startsWith(b) --判断字符串a,是不是以字符串b开头 a.endsWith(b) --判断字符串a,是不是以字符串b结尾

  5. C语言基础 (2) linux命令

    01.课程回顾 链接 ln 1.txt aaa.txt  硬链接 (两个相互独立 删除一个另外一个还在) ln -s 1.txt aaa.txt软连接 (后面的是快捷方式) 硬链接只能是文件,软连接可 ...

  6. POJ-1511 Invitation Cards 往返最短路 邻接表 大量数据下的处理方法

    题目链接:https://cn.vjudge.net/problem/POJ-1511 题意 给出一个图 求从节点1到任意节点的往返路程和 思路 没有考虑稀疏图,上手给了一个Dijsktra(按紫书上 ...

  7. CF1065D Three Pieces (多元最短路)

    题目大意:给你一个棋盘,你需要控制棋子依次经过编号为1~n的所有点,棋子的可以是车,马,象,都依照国际象棋的行棋方式,每走一步消耗1单位时间,但每次更换棋子都需要额外1单位时间,求经过所有点需要的最少 ...

  8. Vue style里面使用@import引入外部css, 作用域是全局的解决方案

    问题描述 使用@import引入外部css,作用域却是全局的 <template> </template> <script> export default { na ...

  9. vue源码之响应式数据

    分析vue是如何实现数据响应的. 前记 现在回顾一下看数据响应的原因. 之前看了vuex和vue-i18n的源码, 他们都有自己内部的vm, 也就是vue实例. 使用的都是vue的响应式数据特性及$w ...

  10. HDU 4725 The Shortest Path in Nya Graph

    he Shortest Path in Nya Graph Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged o ...