Description

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<=5000

0<=M<=3000
 
1<=Ui,Vi<=N+2
0<=Ai,Bi<=500
0<=Ci<=10000
0<=Di<=1000
 
很久之前就想做这道题了...
上午叶大佬给我看了APIO2017 T3后,特别想找一道0/1分数规划打一打
这个题首先分数规划的思路是比较显然的...设答案为mid,wi为一次操作的贡献,n为次数;
X-Y>=mid*n;
X-(X+∑wi)>=mid*n=mid*∑1;
X-(X+∑wi+mid)>=0;
∑wi+mid<=0;
那么我们就是需要判断∑wi+mid的最小值<=0;
首先可以很好的知道缩一条边的贡献是ai-di,扩大一条边的贡献是bi+di;
但是我们必须满足流量不变且每条边满载,
然后我发现修改一条边是牵一发而动全身的,为了一条边需要修改一连串的边且要一直到起点出来的那条边.
然后就觉得很完蛋...其实好像可以用判负圈那套理论...
于是在网上看到了一种很有道理的想法.是一种基于调整的思路.
假设先把所有的道路压缩为0,那么初始费用为:∑(ai-di+mid)*ci;
然后用费用流进行调整:
对于原图中的每条边进行两种调整:
1.连容量为c,费用为-(ai-di+mid)的边;
2.连容量为Inf,费用为(bi+di+mid)的边;(从起点出发的不连)
对于第一种边表示撤回原来的压缩操作,对于第二种边表示进行扩大操作.
 
这样做的正确性:
1.由于是最小费用最大流所以会优先增广第一种费用小的边,所以一定是把所有压缩操作撤回了,再考虑扩大操作的
2.由于是最小费用最大流,所以新图的最大流和原图相等,流量平衡了
妙不可言
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define RG register
using namespace std;
const int N=100000;
const int Inf=19260817;
const double eps=1e-5;
int head[N],nxt[N],to[N],s[N],fa[N],cnt=1,n,m,S,T,tt;
int w[N],ti[N],vis[N],q[N*10];
double c[N],dis[N],cost,ans;
struct data{
int u,v,a,b,c,d;
}a[N];
inline void Addedge(RG int x,RG int y,RG int z,RG double v){
to[++cnt]=y,nxt[cnt]=head[x],s[cnt]=z,c[cnt]=v,head[x]=cnt;
}
inline void lnk(RG int x,RG int y,RG int z,RG double v){
Addedge(x,y,z,v);Addedge(y,x,0,-v);
}
inline bool spfa(){
for(RG int i=1;i<=T;i++) vis[i]=0,dis[i]=Inf;
int t=0,sum=1;q[0]=S,vis[S]=1,dis[S]=0;
while(t<sum){
int now=q[t++];vis[now]=0;
for(RG int i=head[now];i;i=nxt[i]){
int y=to[i];
if(dis[y]>dis[now]+c[i]&&s[i]){
fa[y]=i;dis[y]=dis[now]+c[i];
if(!vis[y]) vis[y]=1,q[sum++]=y;
}
}
}
if(abs(dis[T]-Inf)<=eps) return 0;
int f=Inf;
for(RG int i=fa[T];i;i=fa[to[i^1]]) f=min(f,s[i]);
for(RG int i=fa[T];i;i=fa[to[i^1]]) s[i]-=f,s[i^1]+=f;
cost+=dis[T]*f;
return 1;
}
void rebuild(double mid){
memset(head,0,sizeof(head));cnt=1;
for(int i=1;i<=m;i++){
lnk(a[i].u,a[i].v,a[i].c,-(-a[i].d+a[i].a+mid));
if(a[i].u!=S) lnk(a[i].u,a[i].v,Inf,a[i].b+a[i].d+mid);
}
}
bool check(double mid){
rebuild(mid);double ret=0;cost=0;
for(int i=1;i<=m;i++){
ret+=(-a[i].d+a[i].a+mid)*a[i].c;
}
while(spfa());
return 0-(ret+cost)>=eps;
}
int main(){
scanf("%d%d",&n,&m);S=n+1,T=n+2;
for(int i=1;i<=m;i++){
scanf("%d%d%d%d%d%d",&a[i].u,&a[i].v,&a[i].a,&a[i].b,&a[i].c,&a[i].d);
}
double l=0,r=30000.0;
while(r-l>=eps){
double mid=(l+r)/2;
if(check(mid)) ans=mid,l=mid;
else r=mid;
}
printf("%.2f",ans);
return 0;
}
 

bzoj 3597: [Scoi2014]方伯伯运椰子的更多相关文章

  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. 3597: [Scoi2014]方伯伯运椰子[分数规划]

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

  5. BZOJ 3597 SCOI2014 方伯伯送椰子 网络流分析+SPFA

    原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3597 Description 四川的方伯伯为了致富,决定引进海南的椰子树.方伯伯的椰子园十 ...

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

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

  7. 2019.03.28 bzoj3597: [Scoi2014]方伯伯运椰子(01分数规划)

    传送门 题意咕咕咕有点麻烦不想写 思路: 考虑加了多少一定要压缩多少,这样可以改造边. 于是可以通过分数规划+spfaspfaspfa解决. 代码: #include<bits/stdc++.h ...

  8. BZOJ3597 SCOI2014方伯伯运椰子(分数规划+spfa)

    即在总流量不变的情况下调整每条边的流量.显然先二分答案变为求最小费用.容易想到直接流量清空跑费用流,但复杂度略有些高. 首先需要知道(不知道也行?)一种平时基本不用的求最小费用流的算法——消圈法.算法 ...

  9. Bzoj3597: [Scoi2014]方伯伯运椰子

    题面 传送门 Sol 消圈定理:如果一个费用流网络的残量网络有负环,那么这个费用流不优 于是这个题就可以建出残量网络,然后分数规划跑负环了 # include <bits/stdc++.h> ...

随机推荐

  1. c# AutoMapper 使用方式

    安装方式:使用vs自带的nuget管理工具,搜索AutoMapper ,选择第一个安装到你的项目即可. 我从网上找了一些资料,下载了个demo,然后自己又写了一遍,我把AutoMapper 的使用分为 ...

  2. 通过YUM升级centOS内核,以便安装docker

    安装Docker要满足一定的条件,对于cents系统,要求必须是64位,并且内核版本是3.10以上. 如果你的centos操作系统内核低于3.10,需要升级到这个版本以上,才能安装docker. 第一 ...

  3. lnmp1.3 配置pathinfo---thinkphp3.2 亲测有效

    lnmp1.3环境下配置pathinfo模式试了很多方法,都以失败告终,博主被这个问题困扰了很久,终于解决了!现记录如下: 1.打开php.ini 通常该文件在 /usr/local/php/etc/ ...

  4. 关于C++编译链接和模板函数

    一,关于编译链接编译指的的把编译单元生成目标文件的过程链接是把目标文件链接到一起的过程编译单元:可以认为是一个.c或者.cpp文件.每个编译单元经过预处理会得到一个临时的编译单元.预处理会间接包含其他 ...

  5. ZTREE改版 -- 增删减 -- 图标字体化 完整改版

    引言 这次主要更新增删改功能以及修复存在的一些bug:图标能动态改变,回调函数添加 ZTREE改版功能完善 前面文章对于改版过程做了较详细的解释,这里就不多加赘述了,直接看效果图: 增加按钮: 修改节 ...

  6. NGUI_概述

    序言:这是张三疯第一次开始NGUI插件的学习,刚开始学习,肯定有很多漏洞,后期会及时的补上的. 希望大家可以见谅,希望大佬多多指教. 一.什么是NGUI: NGUI是严格遵循KISS原则并用C#编写的 ...

  7. Azure ARM (18) 将传统的ASM VM迁移到ARM VM (1)

    <Windows Azure Platform 系列文章目录> 目前很多客户陆续的把传统ASM VM迁移至ARM VM.我这里简单介绍一下. 整个迁移过程分为: 1.Validate,Az ...

  8. linux 开机批量启动程序

    每天早上到公司第一件事打开电脑,打开我的qq.我的开发工具idea.在看看邮件,日复一日,变懒了.也变聪明了,写了以下一段脚本 文件名称:mystart.sh #!bin/bash #检验我的开发工具 ...

  9. Android安全专项-利用androguard分析微信

    androguard Androguard经常使用API学习1 安装 做 Android 安全測试之前你应该知道的工具 (一) 分析 ./androlyze.py -s进入分析的交互界面 然后运行 a ...

  10. SOJ--Zig-Zag

    Zig-Zag 在图形图像处理中经常须要将一个二维的图像矩阵转化为一维的向量.二维化一维的过程实际上就是将二维数组的元素按某种顺序构成一维数组. 一种经常使用的序列叫"Zig-Zag&quo ...