zoukankan      html  css  js  c++  java
  • [P1768]天路(分数规划+SPFA判负环)

    题目描述

    “那是一条神奇的天路诶~,把第一个神犇送上天堂~”,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判负环即可,注意要用DFS版的SPFA(这么重要的算法我以前竟然毫无所知)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=l; i<=r; i++)
     5 using namespace std;
     6 
     7 const int N=200010;
     8 struct P{ int to,nxt; double v1,v2; }e[N<<1];
     9 int n,m,u,v,len,h[N],vis[N],flag;
    10 double w1,w2,dis[N];
    11 
    12 void spfa(double now,int x){
    13     if (flag) return;
    14     vis[x]=1;
    15     for (int i=h[x],k; i; i=e[i].nxt)
    16         if (dis[k=e[i].to]>dis[x]+now*e[i].v2-e[i].v1){
    17             dis[k]=dis[x]+now*e[i].v2-e[i].v1;
    18             if (!vis[k]) spfa(now,k); else { flag=1; return; }
    19         }
    20     vis[x]=0;
    21 }
    22 
    23 bool check(double now){
    24     flag=0;
    25     memset(dis,0,sizeof(dis));
    26     memset(vis,0,sizeof(vis));
    27     rep(i,1,n){
    28         spfa(now,i);
    29         if (flag)break;
    30     }
    31     if (flag) return 1; return 0;
    32 }
    33 
    34 int main(){
    35     scanf("%d %d",&n,&m);
    36     rep(i,1,m){
    37         scanf("%d %d %lf %lf",&u,&v,&w1,&w2);
    38         e[++len].to=v; e[len].v1=w1; e[len].v2=w2; e[len].nxt=h[u]; h[u]=len;
    39     }
    40     double l=0,r=200.0,mid;
    41     while (l+0.01<r){
    42         mid=(l+r)/2;
    43         if (check(mid))l=mid; else r=mid;
    44     }
    45     if (l==0) printf("-1"); else printf("%.1lf",r);
    46     return 0;
    47 }
  • 相关阅读:
    Lucene in action 笔记 case study
    关于Restful Web Service的一些理解
    Lucene in action 笔记 analysis篇
    Lucene in action 笔记 index篇
    Lucene in action 笔记 term vector
    Lucene in action 笔记 search篇
    博客园开博记录
    数论(算法概述)
    DIV, IFRAME, Select, Span标签入门
    记一个较困难的SharePoint性能问题的分析和解决
  • 原文地址:https://www.cnblogs.com/HocRiser/p/8462839.html
Copyright © 2011-2022 走看看