原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3597

Description

四川的方伯伯为了致富,决定引进海南的椰子树。方伯伯的椰子园十分现代化,椰子园中有一套独特的交通系统。

现在用点来表示交通节点,边来表示道路。这样,方伯伯的椰子园就可以看作一个有 n + 2 个交通节点,m条边的有向无环图。n +1 号点为入口,n +2 号点为出口。每条道路都有 6 个参数,ui,vi,ai,bi,ci,di,分别表示,该道路从 ui 号点通向 vi 号点,将它的容量压缩一次要 ai 的花费,容量扩大一次要 bi 的花费,该条道路当前的运输容量上限为 ci,并且每单位运输量通过该道路要 di 的费用。

在这个交通网络中,只有一条道路与起点相连。因为弄坏了这条道路就会导致整个交通网络瘫痪,聪明的方伯伯决定绝不对这条道路进行调整,也就是说,现在除了这条道路之外,对其余道路都可以进行调整。

有两种调整方式:

  1. 选择一条道路,将其进行一次压缩,这条道路的容量会下降 1 单位。

  2. 选择一条道路,将其进行一次扩容,这条道路的容量会上升 1 单位。

一条道路可以被多次调整。

由于很久以前,方伯伯就请过一个工程师,对这个交通网络进行过一次大的优化调整。所以现在所有的道路都被完全的利用起来了,即每条道路的负荷都是满的(每条道路的流量等于其容量)。

但方伯伯一想到自己的海南椰子会大丰收,就十分担心巨大的运输量下,会导致过多的花费。因此,方伯伯决定至少进行一次调整,调整之后,必须要保持每条道路满负荷,且总交通量不会减少。

设调整后的总费用是 Y,调整之前的总费用是 X。现在方伯伯想知道,最优调整比率是多少,即假设他进行了 k 次调整,(X - Y)/k最大能是多少?

注:总费用 = 交通网络的运输花费 + 调整的花费

Input

第一行包含二个整数N,M接下来M行代表M条边,表示这个交通网络每行六个整数,表示Ui,Vi,Ai,Bi,Ci,Di接下来一行包含一条边,表示连接起点的边

Output

一个浮点数,保留二位小数。表示答案,数据保证答案大于0

Sample Input

5 10
1 5 13 13 0 412
2 5 30 18 396 148
1 5 33 31 0 39
4 5 22 4 0 786
4 5 13 32 0 561
4 5 3 48 0 460
2 5 32 47 604 258
5 7 44 37 75 164
5 7 34 50 925 441
6 2 26 38 1000 22

Sample Output

103.00

HINT

1<=N<=500,0<=M<=3000,1<=Ui,Vi<=N+2,0<=Ai,Bi<=500,0<=Ci<=10000,0<=Di<=1000

题意概述:
  给出一个N+2个点M条边的DAG图,这是一张网络,每条边有缩容1的代价a,扩容1的代价b,流量上限c,流量费用d。一开始网络中每条边都是满流的。现在可以对网络进行一些调整(不包括和起点相连的唯一的那条边),调整之后使得网络中的所有边依旧满流(即同时流量大小不变)。
  假设进行了K次调整,调整之前的总流量费用为X,调整中花费的费用以及调整之后的流量费用为Y,问(X-Y)/K的最大值(答案保证大于0)。

分析:
  哎呀呀先分析性质。。。。。
  题目给的(X-Y)/K长得很难看。。发现每一次操作只会让某一条边新的流量的代价增加/减少单位代价,所以说这个式子实际上求的是合法调整方案每次操作的单位代价。
  最终的总流量不能变,那么事实上我们不能增流或者减流,只能调整流量。在残量网络之中一个合法的改流对应了一个环(可以递归证明,因为这是个DAG图所以不存在正权环无效改流的情况)。对于一次增流操作,付出的代价为d+b;对于一次减流操作,得到的收益为d-a。当存在一个环中所有边的调整代价为负数,即得到一个负权环的时候,这种调整给我们带来了收益。
  题目的问法显然是个最优比率问题,那么考虑二分答案。假设当前二分到的值为m,假设存在一种方案,所有被操作的边的收益和为sum,操作边的数量为cnt,那么有sum/cnt>=m,虽然这其中可能有很多个环,但是根据糖水原理一定至少包含一个环单独满足这个性质。于是对于这单独的一个环,式子变成:cnt*m-sum<=0,cnt表示的是环上边的数量。分到每条边的头上就是sum{m-w}<=0,其中w代表的是这条边的收益(原图的边正向连边,收益-(d+b),反向连边,收益为(d-a))。对于原图中没有流量的边,不连反向边。二分答案的时候看有没有负权环,有的话说明答案成立,可以往大猜,否则不成立,只能往小猜。
  二分下界为0,上界为所有边d的和。
  最坏时间复杂度:O((34)*N*M)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
#define inf (1e9+5)
using namespace std;
const int maxn=;
const int maxm=;
const double eps=1e-; int N,M;
struct net_edge{ int u,v,a,b,c,d; }NE[maxm];
struct edge{ int to,next; double w; }E[maxm<<];
int first[maxn],np,inq[maxn],inc[maxn],sum; double dist[maxn]; void data_in()
{
scanf("%d%d",&N,&M);
for(int i=;i<=M;i++){
scanf("%d%d%d%d%d%d",&NE[i].u,&NE[i].v,&NE[i].a,&NE[i].b,&NE[i].c,&NE[i].d);
sum+=NE[i].d;
}
}
void add_edge(int u,int v,double w)
{
E[++np]=(edge){v,first[u],w};
first[u]=np;
}
bool SPFA()
{
for(int i=;i<=N+;i++) dist[i]=inf,inc[i]=inq[i]=;
queue<int>q;
q.push(N+);
dist[N+]=,inq[N+]=,inc[N+]=;
while(!q.empty()){
int i=q.front(); q.pop();
inq[i]=;
for(int p=first[i];p;p=E[p].next){
int j=E[p].to;
if(dist[i]+E[p].w<dist[j]){
dist[j]=dist[i]+E[p].w,
if(!inq[j]){
if(++inc[j]==N+) return ;
inq[j]=,q.push(j);
}
}
}
}
return ;
}
bool check(double m)
{
memset(first,,sizeof(first));
np=;
for(int i=;i<=M;i++){
add_edge(NE[i].u,NE[i].v,m+(NE[i].d+NE[i].b));
if(NE[i].c) add_edge(NE[i].v,NE[i].u,m-(NE[i].d-NE[i].a));
}
return SPFA();
}
void work()
{
double L=,R=sum,mid,ans=;
while(R-L>=eps){
mid=(L+R)/;
if(check(mid)) ans=mid,L=mid;
else R=mid;
}
printf("%.2f\n",ans);
}
int main()
{
data_in();
work();
return ;
}

BZOJ 3597 SCOI2014 方伯伯送椰子 网络流分析+SPFA的更多相关文章

  1. bzoj 3597: [Scoi2014]方伯伯运椰子 0/1分数规划

    3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 144  Solved: 78[Submit][Status ...

  2. bzoj 3597: [Scoi2014]方伯伯运椰子 [01分数规划 消圈定理 spfa负环]

    3597: [Scoi2014]方伯伯运椰子 题意: from mhy12345 给你一个满流网络,对于每一条边,压缩容量1 需要费用ai,扩展容量1 需要bi, 当前容量上限ci,每单位通过该边花费 ...

  3. bzoj 3597 [Scoi2014] 方伯伯运椰子 - 费用流 - 二分答案

    题目传送门 传送门 题目大意 给定一个费用流,每条边有一个初始流量$c_i$和单位流量费用$d_i$,增加一条边的1单位的流量需要花费$b_i$的代价而减少一条边的1单位的流量需要花费$a_i$的代价 ...

  4. bzoj 3597: [Scoi2014]方伯伯运椰子

    Description Input 第一行包含二个整数N,M 接下来M行代表M条边,表示这个交通网络 每行六个整数,表示Ui,Vi,Ai,Bi,Ci,Di 接下来一行包含一条边,表示连接起点的边 Ou ...

  5. 3597: [Scoi2014]方伯伯运椰子[分数规划]

    3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec  Memory Limit: 64 MB Submit: 404  Solved: 249 [Submit][Sta ...

  6. 洛谷3288 SCOI2014方伯伯运椰子(分数规划+spfa)

    纪念博客又一次爆炸了 首先,对于本题中,我们可以发现,保证存在正整数解,就表示一定费用会降低.又因为一旦加大的流量,费用一定会变大,所以总流量一定是不变的 那么我们这时候就需要考虑一个退流的过程 对于 ...

  7. bzoj3597[Scoi2014]方伯伯运椰子 01分数规划+spfa判负环

    3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 594  Solved: 360[Submit][Statu ...

  8. bzoj 3594: [Scoi2014]方伯伯的玉米田 dp树状数组优化

    3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 314  Solved: 132[Submit][Sta ...

  9. BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap

    3595: [Scoi2014]方伯伯的Oj Time Limit: 6 Sec  Memory Limit: 256 MBSubmit: 102  Solved: 54[Submit][Status ...

随机推荐

  1. 前端路由原理及vue-router介绍

    前端路由原理本质就是监听 URL 的变化,然后匹配路由规则,显示相应的页面,并且无须刷新.目前单页面使用的路由就只有两种实现方式 hash history www.test.com/##/ 就是 Ha ...

  2. CSS 中定位方式有几种,说明他们的意义

    1.static  默认定位方式 显示为没有设置定位时的位置 2.fixed(固定定位)  他所相对固定的对象是可视窗口,与其他无关.以浏览器窗口作为参考进行定位 3.relative(相对定位) 元 ...

  3. JNI 和 socket api

    1.JavaVM 和 JNIEnvJNIEnv是一个与线程相关的变量,不同线程的JNIEnv彼此独立.JavaVM是虚拟机在JNI层的代表,在一个虚拟机进程中只有一个JavaVM,因此该进程的所有线程 ...

  4. vi常用命令学习

    (1)移动光标 h : 左移光标l : 右移光标j : 下移光标k : 上移光标 w : 移动到下一个单词词头b : 移动到上一个单词词头e : 移动到本单词的尾部 0 :移动到当前行的开端$ :移动 ...

  5. 【SQL】Oracle的交集、并集、差集

    假设有表tableA.tableB,他们都有字段id和name 交集:INTERSECT (适用于两个结果集) select a.id, a.name from tableA a INTERSECT ...

  6. 并发编程之多线程基础-join方法及优先级(五)

    join()方法作用 当在主线程当中执行到t1.join()方法时,就认为主线程应该把执行权让给t1 优先级 现代操作系统基本采用时分的形式调度运行的线程,线程分配得到的时间片的多少决定了线程使用处理 ...

  7. cornerstone提交报错"but is missing"以及xocde提示"missing from working copy"

    问题描述 xocde提示"missing from working copy" 虽然这种警告不会影响程序到运行,但是数量很多,而且在svn提交的时候回出现这种问题 使用的svn工具 ...

  8. 工具类(设置控件 frame) - iOS

    为了便于日常开发效率,因此创建了一些小的工具类便于使用. 具体 code 如下: 声明: #import <UIKit/UIKit.h> @interface UIView (Frame) ...

  9. java面向对象编程思想的理解

    1.我们总说java是一门面向对象编程的语言,那什么是面向对象呢? 我是这样理解的,对象是事物存在的实体,如,猪.狗,花早等都是对象,对象由两部分组成.面向对象编程的三大特点:继承,多态,类是封装对象 ...

  10. C++练习--创建Boat类和Car类(含友元)

    /* 定义Boat与Car两个类,二者都有weight属性, 定义二者的一个友元函数totalWeight()为外部函数, 计算二者的重量和. */ #include<iostream> ...