题目

Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识。

最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量。一个合法的网络流方案必须满足:(1)每条边的实际流量都不超过其最大流量且非负;(2)除了源点S和汇点T之外,对于其余所有点,都满足该点总流入流量等于该点总流出流量;而S点的净流出流量等于T点的净流入流量,这个值也即该网络流方案的总运输量。最大流问题就是对于给定的运输网络,求总运输量最大的网络流方案。

上图表示了一个最大流问题。对于每条边,右边的数代表该边的最大流量,左边的数代表在最优解中,该边的实际流量。需要注意到,一个最大流问题的解可能不是唯一的。 对于一张给定的运输网络,Alice先确定一个最大流,如果有多种解,Alice可以任选一种;之后Bob在每条边上分配单位花费(单位花费必须是非负实数),要求所有边的单位花费之和等于P。总费用等于每一条边的实际流量乘以该边的单位花费。需要注意到,Bob在分配单位花费之前,已经知道Alice所给出的最大流方案。现茌Alice希望总费用尽量小,而Bob希望总费用尽量大。我们想知道,如果两个人都执行最优策略,最大流的值和总费用分别为多少。

输入格式

  1. 第一行三个整数NMPN表示给定运输网络中节点的数量,M表示有向边的数量,P的含义见问题描述部分。为了简化问题,我们假设源点S是点1,汇点T是点N
  2. 接下来M行,每行三个整数ABC,表示有一条从点A到点B的有向边,其最大流量是C

输出格式

第一行一个整数,表示最大流的值。

第二行一个实数,表示总费用。建议选手输出四位以上小数。

输入样例

3 2 1

1 2 10

2 3 15

输出样例

10

10.0000

提示

【样例说明】

  1. 对于Alice,最大流的方案是固定的。两条边的实际流量都为10
  2. 对于Bob,给第一条边分配0.5的费用,第二条边分配0.5的费用。总费用

为:100.5+100.5=10。可以证明不存在总费用更大的分配方案。

【数据规模和约定】

  1. 对于20%的测试数据:所有有向边的最大流量都是1
  2. 对于100%的测试数据:N < = 100M < = 1000
  3. 对于l00%的测试数据:所有点的编号在I..N范围内。1 < = 每条边的最大流

量 < = 50000。1 < = P < = 10。给定运输网络中不会有起点和终点相同的边。

题解

首先,Bob的最优策略一定是将所有权值加到流量最大的边上

所以Alice应使在最大流前提下使最大流量的边最小

那么二分所有边的上限判定可行性就可以了

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<queue>
  5. #include<cstring>
  6. #include<algorithm>
  7. #define eps 1e-8
  8. #define LL long long int
  9. #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
  10. #define REP(i,n) for (int i = 1; i <= (n); i++)
  11. #define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
  12. using namespace std;
  13. const int maxn = 105,maxm = 5005,INF = 1000000000;
  14. inline int read(){
  15. int out = 0,flag = 1; char c = getchar();
  16. while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
  17. while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
  18. return out * flag;
  19. }
  20. int n,m,h[maxn],ne = 2,S,T;
  21. double P,M;
  22. struct EDGE{int to,nxt; double f,cap;}ed[maxm];
  23. inline void build(int u,int v,double w){
  24. ed[ne] = (EDGE){v,h[u],w,w}; h[u] = ne++;
  25. ed[ne] = (EDGE){u,h[v],0,0}; h[v] = ne++;
  26. }
  27. int d[maxn],vis[maxn],cur[maxn];
  28. queue<int> q;
  29. bool bfs(){
  30. for (int i = 1; i <= n; i++) d[i] = INF,vis[i] = false;
  31. q.push(S); d[S] = 0; vis[S] = true;
  32. int u;
  33. while (!q.empty()){
  34. u = q.front(); q.pop();
  35. Redge(u) if (fabs(ed[k].f) > eps && !vis[to = ed[k].to]){
  36. d[to] = d[u] + 1; vis[to] = true;
  37. q.push(to);
  38. }
  39. }
  40. return vis[T];
  41. }
  42. double dfs(int u,double minf){
  43. if (u == T || fabs(minf) < eps) return minf;
  44. double flow,f; int to;
  45. if (cur[u] == -1) cur[u] = h[u];
  46. for (int& k = cur[u]; k; k = ed[k].nxt)
  47. if (d[to = ed[k].to] == d[u] + 1 && fabs(f = dfs(to,min(minf,ed[k].f))) > eps){
  48. ed[k].f -= f; ed[k ^ 1].f += f;
  49. flow += f; minf -= f;
  50. if (fabs(minf) < eps) break;
  51. }
  52. return flow;
  53. }
  54. double maxflow(){
  55. double flow = 0;
  56. while (bfs()){
  57. memset(cur,-1,sizeof(cur));
  58. flow += dfs(S,INF);
  59. }
  60. return flow;
  61. }
  62. bool check(double cap){
  63. for (int i = 2; i < ne; i += 2){
  64. ed[i ^ 1].f = 0;
  65. ed[i].f = min(ed[i].cap,cap);
  66. }
  67. return maxflow() >= M;
  68. }
  69. void solve(){
  70. M = maxflow();
  71. double l = 0,r = 50000,mid;
  72. while ((r - l) > 1e-4){
  73. mid = (l + r) / 2;
  74. if (check(mid)) r = mid;
  75. else l = mid;
  76. }
  77. printf("%.lf\n%.4lf\n",M,l * P);
  78. }
  79. int main(){
  80. n = read(); m = read(); P = read(); S = 1; T = n;
  81. int a,b,w;
  82. for (int i = 1; i <= m; i++){
  83. a = read(); b = read(); w = read();
  84. build(a,b,w);
  85. }
  86. solve();
  87. return 0;
  88. }

BZOJ3130 [Sdoi2013]费用流 【网络流 + 二分】的更多相关文章

  1. BZOJ 3130: [Sdoi2013]费用流 网络流+二分

    3130: [Sdoi2013]费用流 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1230  Solved: ...

  2. BZOJ 3130: [Sdoi2013]费用流 网络流 二分 最大流

    https://www.lydsy.com/JudgeOnline/problem.php?id=3130 本来找费用流的题,权当复习一下网络流好了. 有点麻烦的是double,干脆判断大小或者二分增 ...

  3. BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]

    3130: [Sdoi2013]费用流 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 960  Solved: 5 ...

  4. bzoj千题计划133:bzoj3130: [Sdoi2013]费用流

    http://www.lydsy.com/JudgeOnline/problem.php?id=3130 第一问就是个最大流 第二问: Bob希望总费用尽量大,那肯定是把所有的花费加到流量最大的那一条 ...

  5. BZOJ3130: [Sdoi2013]费用流(二分,最大流)

    Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识.    最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络 ...

  6. 【二分答案】【最大流】bzoj3130 [Sdoi2013]费用流

    二分最大的边的cap,记作Lim. 把所有的边的cap设为min(Lim,cap[i]). Bob一定会把单位费用加到最大边上. #include<cstdio> #include< ...

  7. BZOJ3130 [Sdoi2013]费用流

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3130 这题codevs上也有,不过数据挂了[要A得看discuss]. 题目大意: Ali ...

  8. bzoj 3130 [Sdoi2013]费用流(二分,最大流)

    Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识.    最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络 ...

  9. BZOJ 3130 [Sdoi2013]费用流 ——网络流

    [题目分析] 很容易想到,可以把P放在流量最大的边上的时候最优. 所以二分网络流,判断什么时候可以达到最大流. 流量不一定是整数,所以需要实数二分,整数是会WA的. [代码] #include < ...

随机推荐

  1. 重置Cacti密码

    Cacti登录密码忘记,重置Cacti密码 用root用户进入系统 [root@localhsot]# mysql -u root -p mysql> show databases; mysql ...

  2. SQLServer查询耗时sql语句

    qs.total_worker_time/qs.execution_count as [Avg CPU Time], , ( ) as query_text, qt.dbid, dbname=db_n ...

  3. ajax上传文件以及使用中常见问题处理

    <script src="/scripts/ajaxfileupload.js"></script> <script src="/scrip ...

  4. ubuntu16 安装elasticsearch6.3问题

    1.ubuntu16 安装elasticsearch6.3 elasticsearch 6.3需要的java的版本是1.8以上 安装java1.8 详见本博客的安装java https://www.c ...

  5. UVA 1347 Tour 双调TSP

    TSP是NP难,但是把问题简化,到最右点之前的巡游路线只能严格向右,到最右边的点以后,返回的时候严格向左,这个问题就可以在多项式时间内求出来了. 定义状态d[i][j]表示一个人在i号点,令一个人在j ...

  6. css--背景和列表

    背景 背景样式: background-color    设置元素的背景颜色 background-image  把图像设置为背景 background-repeat     设置背景图像是否重复及如 ...

  7. Bootstrap 表格2

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  8. Luogu P2664 树上游戏 dfs+树上统计

    题目: P2664 树上游戏 分析: 本来是练习点分治的时候看到了这道题.无意中发现题解中有一种方法可以O(N)解决这道题,就去膜拜了一下. 这个方法是,假如对于某一种颜色,将所有这种颜色的点全部删去 ...

  9. UVa-12096-集合栈计算机

    这题的话,我们读入操作之后,首先对于空集就是初始化为空. 我们可以使用typedef 对于 set 重命名为Set,这样就可以直接用Set()的语法进行空集的初始化了. 这题主要是对于集合的处理,我们 ...

  10. java获取时间格式

    文章来源:https://www.cnblogs.com/hello-tl/p/9263602.html package com.util; import java.text.SimpleDateFo ...