zoukankan      html  css  js  c++  java
  • luogu P1768 天路

    题目描述

    “那是一条神奇的天路诶~,把第一个神犇送上天堂~”,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以内.

    spfa判环+二分答案

    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,m;
    const int N=200000;
    float p[N],v[N];
    struct node{
        int to,next;float p,v,w;
    }edge[N];int head[N],num=0;
    inline void add_edge(int x,int y,float p,float v)
    {
        edge[++num].to=y;edge[num].next=head[x];edge[num].p=p;edge[num].v=v;head[x]=num;
    }
    bool vis[N];float dis[N],mid;
    inline bool spfa(int x)
    {
        vis[x]=1;
        for(int i=head[x];i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dis[x]+edge[i].w<dis[v])
            {
                
                if(vis[v]==1)return false;
                dis[v]=dis[x]+edge[i].w;
                if(spfa(v)==false) return false;
            }
        }
        vis[x]=0;
        return true;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        int a,b;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%f%f",&a,&b,&v[i],&p[i]);
            add_edge(a,b,p[i],v[i]);
        }
        for(int i=1;i<=n;i++) add_edge(0,i,0,0);
        float l=0,r=200;
        while(l+0.01<r)
        {
            mid=(l+r)/2.0;
            memset(vis,0,sizeof (vis));
            memset(dis,127,sizeof (dis));
            dis[0]=0;
            for(int x=1;x<=n;x++)
                for(int y=head[x];y;y=edge[y].next)
                    edge[y].w=mid*edge[y].p-edge[y].v;
            if(!spfa(0))l=mid;
            else r=mid;
        }
        if(l==0)puts("-1");
        else printf("%.1lf
    ",r);
        return 0;
    }
     
    

      

  • 相关阅读:
    LOJ 3055 「HNOI2019」JOJO—— kmp自动机+主席树
    LOJ 2586 「APIO2018」选圆圈——KD树
    bzoj 3600 没有人的算术——二叉查找树动态标号
    bzoj 1257 余数之和 —— 数论分块
    bzoj 3998 弦论 —— 后缀自动机
    bzoj 2946 公共串 —— 后缀自动机
    bzoj 4032 [ HEOI 2015 ] 最短不公共子串 —— 后缀自动机+序列自动机
    bzoj 2555 SubString —— 后缀自动机+LCT
    洛谷 P3804 [模板] 后缀自动机
    洛谷 P4106 / bzoj 3614 [ HEOI 2014 ] 逻辑翻译 —— 思路+递归
  • 原文地址:https://www.cnblogs.com/sssy/p/7143235.html
Copyright © 2011-2022 走看看