BZOJ3130 [Sdoi2013]费用流 【网络流 + 二分】
题目
Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识。
最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量。一个合法的网络流方案必须满足:(1)每条边的实际流量都不超过其最大流量且非负;(2)除了源点S和汇点T之外,对于其余所有点,都满足该点总流入流量等于该点总流出流量;而S点的净流出流量等于T点的净流入流量,这个值也即该网络流方案的总运输量。最大流问题就是对于给定的运输网络,求总运输量最大的网络流方案。
上图表示了一个最大流问题。对于每条边,右边的数代表该边的最大流量,左边的数代表在最优解中,该边的实际流量。需要注意到,一个最大流问题的解可能不是唯一的。 对于一张给定的运输网络,Alice先确定一个最大流,如果有多种解,Alice可以任选一种;之后Bob在每条边上分配单位花费(单位花费必须是非负实数),要求所有边的单位花费之和等于P。总费用等于每一条边的实际流量乘以该边的单位花费。需要注意到,Bob在分配单位花费之前,已经知道Alice所给出的最大流方案。现茌Alice希望总费用尽量小,而Bob希望总费用尽量大。我们想知道,如果两个人都执行最优策略,最大流的值和总费用分别为多少。
输入格式
第一行三个整数N,M,P。N表示给定运输网络中节点的数量,M表示有向边的数量,P的含义见问题描述部分。为了简化问题,我们假设源点S是点1,汇点T是点N。
接下来M行,每行三个整数A,B,C,表示有一条从点A到点B的有向边,其最大流量是C。
输出格式
第一行一个整数,表示最大流的值。
第二行一个实数,表示总费用。建议选手输出四位以上小数。
输入样例
3 2 1
1 2 10
2 3 15
输出样例
10
10.0000
提示
【样例说明】
对于Alice,最大流的方案是固定的。两条边的实际流量都为10。
对于Bob,给第一条边分配0.5的费用,第二条边分配0.5的费用。总费用
为:100.5+100.5=10。可以证明不存在总费用更大的分配方案。
【数据规模和约定】
对于20%的测试数据:所有有向边的最大流量都是1。
对于100%的测试数据:N < = 100,M < = 1000。
对于l00%的测试数据:所有点的编号在I..N范围内。1 < = 每条边的最大流
量 < = 50000。1 < = P < = 10。给定运输网络中不会有起点和终点相同的边。
题解
首先,Bob的最优策略一定是将所有权值加到流量最大的边上
所以Alice应使在最大流前提下使最大流量的边最小
那么二分所有边的上限判定可行性就可以了
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
#define eps 1e-8
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 105,maxm = 5005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int n,m,h[maxn],ne = 2,S,T;
double P,M;
struct EDGE{int to,nxt; double f,cap;}ed[maxm];
inline void build(int u,int v,double w){
ed[ne] = (EDGE){v,h[u],w,w}; h[u] = ne++;
ed[ne] = (EDGE){u,h[v],0,0}; h[v] = ne++;
}
int d[maxn],vis[maxn],cur[maxn];
queue<int> q;
bool bfs(){
for (int i = 1; i <= n; i++) d[i] = INF,vis[i] = false;
q.push(S); d[S] = 0; vis[S] = true;
int u;
while (!q.empty()){
u = q.front(); q.pop();
Redge(u) if (fabs(ed[k].f) > eps && !vis[to = ed[k].to]){
d[to] = d[u] + 1; vis[to] = true;
q.push(to);
}
}
return vis[T];
}
double dfs(int u,double minf){
if (u == T || fabs(minf) < eps) return minf;
double flow,f; int to;
if (cur[u] == -1) cur[u] = h[u];
for (int& k = cur[u]; k; k = ed[k].nxt)
if (d[to = ed[k].to] == d[u] + 1 && fabs(f = dfs(to,min(minf,ed[k].f))) > eps){
ed[k].f -= f; ed[k ^ 1].f += f;
flow += f; minf -= f;
if (fabs(minf) < eps) break;
}
return flow;
}
double maxflow(){
double flow = 0;
while (bfs()){
memset(cur,-1,sizeof(cur));
flow += dfs(S,INF);
}
return flow;
}
bool check(double cap){
for (int i = 2; i < ne; i += 2){
ed[i ^ 1].f = 0;
ed[i].f = min(ed[i].cap,cap);
}
return maxflow() >= M;
}
void solve(){
M = maxflow();
double l = 0,r = 50000,mid;
while ((r - l) > 1e-4){
mid = (l + r) / 2;
if (check(mid)) r = mid;
else l = mid;
}
printf("%.lf\n%.4lf\n",M,l * P);
}
int main(){
n = read(); m = read(); P = read(); S = 1; T = n;
int a,b,w;
for (int i = 1; i <= m; i++){
a = read(); b = read(); w = read();
build(a,b,w);
}
solve();
return 0;
}
BZOJ3130 [Sdoi2013]费用流 【网络流 + 二分】的更多相关文章
- BZOJ 3130: [Sdoi2013]费用流 网络流+二分
3130: [Sdoi2013]费用流 Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1230 Solved: ...
- BZOJ 3130: [Sdoi2013]费用流 网络流 二分 最大流
https://www.lydsy.com/JudgeOnline/problem.php?id=3130 本来找费用流的题,权当复习一下网络流好了. 有点麻烦的是double,干脆判断大小或者二分增 ...
- BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]
3130: [Sdoi2013]费用流 Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 960 Solved: 5 ...
- bzoj千题计划133:bzoj3130: [Sdoi2013]费用流
http://www.lydsy.com/JudgeOnline/problem.php?id=3130 第一问就是个最大流 第二问: Bob希望总费用尽量大,那肯定是把所有的花费加到流量最大的那一条 ...
- BZOJ3130: [Sdoi2013]费用流(二分,最大流)
Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识. 最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络 ...
- 【二分答案】【最大流】bzoj3130 [Sdoi2013]费用流
二分最大的边的cap,记作Lim. 把所有的边的cap设为min(Lim,cap[i]). Bob一定会把单位费用加到最大边上. #include<cstdio> #include< ...
- BZOJ3130 [Sdoi2013]费用流
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3130 这题codevs上也有,不过数据挂了[要A得看discuss]. 题目大意: Ali ...
- bzoj 3130 [Sdoi2013]费用流(二分,最大流)
Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识. 最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络 ...
- BZOJ 3130 [Sdoi2013]费用流 ——网络流
[题目分析] 很容易想到,可以把P放在流量最大的边上的时候最优. 所以二分网络流,判断什么时候可以达到最大流. 流量不一定是整数,所以需要实数二分,整数是会WA的. [代码] #include < ...
随机推荐
- "xxadmin" user: No protocol specified 错误
1 查看DISPLAY是否设置:env| grep DISPLAY 如未设置则,export DISPLAY=192.168.0.9:0.0 (斜体字修改为自己的服务器的ip) 2 root用户执 ...
- 洛谷 P2910 [USACO08OPEN]寻宝之路Clear And Present Danger
题目描述 Farmer John is on a boat seeking fabled treasure on one of the N (1 <= N <= 100) islands ...
- 如何用JavaScript判断前端应用运行环境(移动平台还是桌面环境)
我们部署在某些云平台或者Web服务器上的前端应用,既可以用PC端浏览器访问,也可以用手机上的浏览器访问. 在前端应用里,有时候我们需要根据运行环境的不同做出对应处理.比如下面这段逻辑,如果判断出应用当 ...
- 讲课笔记3——CSS
背景常见样式: width:600px; height:800px; background: url(bg.jpg) no-repeat 40px 20px fixed gray ; * ...
- 【图文并茂】DEV配置NTL库
一开始根据陈老师的博客:再说如何在DEV C++中搭建NTL库 后来发现自己虽然跟着一步一步来做,还是做错了很多回. 究竟怎么一回事呢?后来我发现一个致命的错误很容易忽视,所以我就重新写一篇博客. 来 ...
- Mybatis generator自动生成代码包括实体,dao,xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration ...
- css--float浮动
前戏 前面我们学习了CSS相关的知识,现在试想一下,如果我们想把两个div放在一行显示,该怎么处理?前面也说过,div是块级标签,默认占一行,这时候如果想要达成效果,那就要用到float了 float ...
- 14.list列表
1).列表的切片 li = ['德玛西亚',[1,2,3],'luokesasi','eson','女神','jingdongi'] l1 = li[0] print(l1) #>>> ...
- 2017年网络空间安全技术大赛部分writeup
作为一个bin小子,这次一个bin都没做出来,我很羞愧. 0x00 拯救鲁班七号 具体操作不多说,直接进入反编译源码阶段 可以看到,只要2处的str等于a就可以了,而str是由1处的checkPass ...
- PAT (Advanced Level) Practise - 1098. Insertion or Heap Sort (25)
http://www.patest.cn/contests/pat-a-practise/1098 According to Wikipedia: Insertion sort iterates, c ...