【BZOJ3597】方伯伯运椰子(分数规划,网络流)
【BZOJ3597】方伯伯运椰子(分数规划,网络流)
题解
给定了一个满流的费用流模型
如果要修改一条边,那么就必须满足流量平衡
也就是会修改一条某两点之间的路径上的所有边
同时还有另外一条路径会进行相反的修改
现在要求最大化\(\frac{X-Y}{K}\)
二分答案\(mid\)
式子变为\(X-Y-K·mid\geq 0\)
换而言之,相当于给每次修改操作额外付出一个代价\(mid\)
要使得费用+修改代价最小
对于扩容我们很好处理
对于每条边再额外连一条边
容量为\(inf\)(可以无限扩容),费用为扩容的费用,同时,每次流过还会产生一个费用
所以扩容的费用是\(b+d\)
但是压缩呢?
对于每次压缩,相当于是退流了
所以,我们给反边的费用额外增加一个压缩的费用
所以这里的费用是\(a-d\)
但是,似乎还是不会做?
我们虽然这样处理了,但是不知道怎么计算结果。
在看了天哥的博客后,我发现了这题真的很妙啊
我们先假设所有的边都被你压缩成零了,产生了一定的费用,这个可以直接算贡献。
接下来我们有两种边
一种是反压缩,我们把压缩的容量给还原,容量是边的容量,费用是\(d-a\)。
另外一种就是扩容,也就是额外新增容量,容量为\(inf\),费用\(b+d\)
再把分数规划给套上去,把每个费用都加上一个\(mid\)(反压缩是减)
这样给源点流量为原图中的流量,做一次费用流就好啦。
然后我们再来想一想我们的分数规划变成了求什么。
本来是让\(X-Y-K·mid\geq 0\)
也就是\(Y+K·mid-X\leq 0\)
因为提前压缩的时候我们已经把所有的流量贡献的费用给减掉了
也就是我们已经减过\(X\)了
所以就是最后费用流的结果+压缩所有边的费用之和要小于\(0\)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 5555
#define inf 1000000000
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n,m,S,T;
int U[MAX],V[MAX],A[MAX],B[MAX],C[MAX],D[MAX];
struct Line{int v,next,w;double fy;}e[50000];
int h[MAX],cnt=2;
inline void Add(int u,int v,int w,double fy)
{
e[cnt]=(Line){v,h[u],w,fy};h[u]=cnt++;
e[cnt]=(Line){u,h[v],0,-fy};h[v]=cnt++;
}
double sum,Sum;
void Build(double mid)
{
memset(h,0,sizeof(h));cnt=2;sum=0;
for(int i=1;i<=m;++i)
{
if(U[i]!=S)Add(U[i],V[i],inf,B[i]+D[i]+mid);
Add(U[i],V[i],C[i],-(A[i]-D[i]+mid));
sum+=C[i]*(A[i]-D[i]+mid);
}
}
int pe[MAX],pv[MAX];
double dis[MAX];
bool vis[MAX];
bool SPFA()
{
for(int i=1;i<=T;++i)dis[i]=1e18;
dis[S]=0;vis[S]=true;
queue<int> Q;Q.push(S);
while(!Q.empty())
{
int u=Q.front();Q.pop();
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(!e[i].w)continue;
if(dis[v]>dis[u]+e[i].fy)
{
dis[v]=dis[u]+e[i].fy;
pv[v]=u;pe[v]=i;
if(!vis[v])vis[v]=true,Q.push(v);
}
}
vis[u]=false;
}
if(dis[T]>=1e18)return false;
int flow=inf;
for(int i=T;i!=S;i=pv[i])flow=min(flow,e[pe[i]].w);
for(int i=T;i!=S;i=pv[i])e[pe[i]].w-=flow,e[pe[i]^1].w+=flow;
sum+=flow*dis[T];
return true;
}
bool check(double mid)
{
Build(mid);
while(SPFA());
return sum<0;
}
int main()
{
n=read();m=read();S=n+1;T=n+2;
for(int i=1;i<=m;++i)
U[i]=read(),V[i]=read(),A[i]=read(),B[i]=read(),C[i]=read(),D[i]=read();
double l=0,r=5e4;
while(r-l>1e-3)
{
double mid=(l+r)/2;
if(check(mid))l=mid;
else r=mid;
}
printf("%.2lf\n",l);
return 0;
}
当然,还有另外一种方法
费用流上的消圈定理:
如果残余网络上还有负环,证明当前不是最优的费用流
因此,构建出残余网络之后直接检查有无负环即可
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 5555
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next;int w;}e[MAX<<2];
int h[MAX],cnt=1;
inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
int n,m,U,V,A,B,C,D;
double dis[MAX];
bool vis[MAX];
bool SPFA(int u,double mid)
{
vis[u]=true;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(dis[v]>dis[u]+e[i].w+mid)
{
dis[v]=dis[u]+e[i].w+mid;
if(vis[v]||SPFA(v,mid))return true;
}
}
vis[u]=false;
return false;
}
bool check(double mid)
{
for(int i=1;i<=n+2;++i)dis[i]=0,vis[i]=false;
for(int i=1;i<=n+2;++i)
if(SPFA(i,mid))return true;
return false;
}
int main()
{
n=read();m=read();
for(int i=1;i<=m;++i)
{
U=read(),V=read(),A=read(),B=read(),C=read(),D=read();
Add(U,V,B+D);if(C)Add(V,U,A-D);
}
double l=0,r=5e4;
while(r-l>1e-3)
{
double mid=(l+r)/2;
if(check(mid))l=mid;
else r=mid;
}
printf("%.2lf\n",l);
return 0;
}
【BZOJ3597】方伯伯运椰子(分数规划,网络流)的更多相关文章
- 3597: [Scoi2014]方伯伯运椰子[分数规划]
3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec Memory Limit: 64 MB Submit: 404 Solved: 249 [Submit][Sta ...
- [bzoj3597][scoi2014]方伯伯运椰子——分数规划,负环
题解 目标就是 \[Maximize\ \lambda = \frac{X-Y}{k}\] 按照分数规划的一般规律, 构造: \[g(\lambda) = \lambda k + Y - X\] 由于 ...
- 洛谷3288 SCOI2014方伯伯运椰子(分数规划+spfa)
纪念博客又一次爆炸了 首先,对于本题中,我们可以发现,保证存在正整数解,就表示一定费用会降低.又因为一旦加大的流量,费用一定会变大,所以总流量一定是不变的 那么我们这时候就需要考虑一个退流的过程 对于 ...
- bzoj3597 方伯伯运椰子
有一个 DAG,有一个源点,一个汇点和很多条边,每条边有花费 $d_i$ 和最大流量 $c_i$,可以花 $b_i$ 的钱把最大流量增加 $1$,花 $a_i$ 的钱把最大流量减少 $1$ 现在要进行 ...
- bzoj3597[Scoi2014]方伯伯运椰子 01分数规划+spfa判负环
3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 594 Solved: 360[Submit][Statu ...
- bzoj 3597: [Scoi2014]方伯伯运椰子 0/1分数规划
3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 144 Solved: 78[Submit][Status ...
- bzoj 3597: [Scoi2014]方伯伯运椰子 [01分数规划 消圈定理 spfa负环]
3597: [Scoi2014]方伯伯运椰子 题意: from mhy12345 给你一个满流网络,对于每一条边,压缩容量1 需要费用ai,扩展容量1 需要bi, 当前容量上限ci,每单位通过该边花费 ...
- 「SCOI2014」方伯伯运椰子 解题报告
「SCOI2014」方伯伯运椰子 可以看出是分数规划 然后我们可以看出其实只需要改变1的流量就可以了,因为每次改变要保证流量守恒,必须流成一个环,在正负性确定的情况下,变几次是无所谓的. 然后按照套路 ...
- BZOJ3597 SCOI2014方伯伯运椰子(分数规划+spfa)
即在总流量不变的情况下调整每条边的流量.显然先二分答案变为求最小费用.容易想到直接流量清空跑费用流,但复杂度略有些高. 首先需要知道(不知道也行?)一种平时基本不用的求最小费用流的算法——消圈法.算法 ...
随机推荐
- matplotlib绘制散点图
参考自Matplotlib Python 画图教程 (莫烦Python)(10)_演讲•公开课_科技_bilibili_哔哩哔哩 https://www.bilibili.com/video/av16 ...
- 20165324 Java实验四 Android程序设计
20165324 Java实验四 Android程序设计 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:何春江 学号:20165324 指导教师:娄嘉鹏 实验日期:2018年5月1 ...
- 我与前端之间不得不说的三天两夜之jQuery
前端基础之jquery 一 jQuery是什么? [1] jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. [2] jQuery是 ...
- 如何获知PHP程序占用多少内存(复制)
想要知道编写的 PHP 脚本需要占用多少内存么?很简单,直接使用 PHP 查看当前分配给 PHP 脚本的内存的函数 memory_get_usage() 就可以了 下面是使用示例: 复制代码 代码如下 ...
- gitHub新项目的上传
github作为一个开源托管平台,除了有机会学习各位大神的开源项目,还能托管自己写的一些小Demo,作为github新进菜鸟,今天就整理下上传Demo所需的命令和操作步骤,防止我这谜一样的记忆力. 1 ...
- java中全面的单例模式多种实现方式总结
单例模式的思想 想整理一些 java 并发相关的知识,不知道从哪开始,想起了单例模式中要考虑的线程安全,就从单例模式开始吧. 以前写过单例模式,这里再重新汇总补充整理一下,单例模式的多种实现. 单例模 ...
- Bridge Serial-Ports over network
https://stackoverflow.com/questions/29207980/bridge-serial-ports-over-network For an application, wh ...
- 保持简单----纪念丹尼斯•里奇(Dennis Ritchie)
http://www.ruanyifeng.com/blog/2011/10/dennis_ritchie.html
- etcd:从应用场景到实现原理的全方位解读 转自infoq
转自 infoq etcd:从应用场景到实现原理的全方位解读 http://www.infoq.com/cn/articles/etcd-interpretation-application-scen ...
- Docker-docker制作镜像
一.下载镜像 a.以daocloud为mirror下载Nginx镜像 配置daocloud为mirror,下载Nginx镜像:(daocloud官网登陆后,发现镜像里找到Nginx镜像) 下载Ngin ...