【JZOJ3215】【SDOI2013】费用流
来源:互联网 发布:网络招聘的工作内容 编辑:程序博客网 时间:2024/04/29 09:48
╰( ̄▽ ̄)╭
对于一张给定的 运输网络 ,Alice 先确定一个最大流 ,如果有多种解, Alice 可以任选一种; 之后 Bob在每条边上分配单位花费 (单位花费必须是非负实数), 要求所有边的单位花费之和等于 P。总费用等于每一条边 的实际流量乘以该边的单位花费。 需要注意到, Bob在分配单位花费之前,已经知道Alice 所给出的最大流方案。
现在 Alice 希望总费用尽量小,而Bob希望总费用尽量大。我们想知道, 如 果两个人都执行最优策略 ,最大流的值和总费用分别为多少。
对于 100% 的测试数据: N≤100 ,M≤1000 。
对于 100% 的测试数据: 所有点的编号在 1..N 范围内。 1≤每条边 的最大 流 量≤50000 。1≤P≤10 。给定运输网络中不会有起点和 终点 相同的边。
(⊙ ▽ ⊙)
显然Bob要把所有费用全部分配给实际流量最大的边。
所以Alice在满足最大流最大之余,使得流量最大的边最小。
所以二分后再用最大流判断就可以了。
( ̄~ ̄)
#include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<string.h>#define ll long long#define eps 10e-7using namespace std;const char* fin="ex3215.in";const char* fout="ex3215.out";const int inf=0x7fffffff;const int maxn=2007;int n,m,n1,i,j,k;int a[maxn][2],fi[maxn],ne[maxn],la[maxn],tot;double l,r,mid,va[maxn],b[maxn],Ans;int bz[maxn],card[maxn];double Abs(double a){ return a>0?a:-a;}void add_line(int a,int b,double c){ tot++; ne[tot]=fi[a]; la[tot]=b; va[tot]=c; fi[a]=tot;}void add(int a,int b,double c){ add_line(a,b,c); add_line(b,a,0);}double gap(int v,double flow){ int i,k; double use=0,j; if (v==n) return flow; for (k=fi[v];k;k=ne[k]) if (bz[la[k]]+1==bz[v] && Abs(va[k])>eps){ j=gap(la[k],min(va[k],flow-use)); use+=j; va[k]-=j; va[k^1]+=j; if (Abs(flow-use)<eps || bz[1]==n) return use; } if (!--card[bz[v]]) bz[1]=n; card[++bz[v]]++; return use;}double flow(){ double ans=0; memset(card,0,sizeof(card)); memset(bz,0,sizeof(bz)); card[0]=n; while (bz[1]<n){ ans+=gap(1,inf); } return ans;}bool judge(double MAX){ int i,j,k; memset(fi,0,sizeof(fi)); tot=1; for (i=1;i<=m;i++) add(a[i][0],a[i][1],min(MAX,b[i])); return Abs(flow()-Ans)<eps;}int main(){ scanf("%d%d%d",&n,&m,&n1); tot=1; for (i=1;i<=m;i++) scanf("%d%d%lf",&a[i][0],&a[i][1],&b[i]),add(a[i][0],a[i][1],b[i]); Ans=flow(); l=0; r=50000; while (r-l>eps){ mid=(l+r)/2; if (judge(mid)) r=mid; else l=mid; } printf("%d\n%.4lf",int(Ans+eps),l*n1 ); return 0;}
(⊙v⊙)
要注意的是网络流的实现时的问题:
double gap(int v,double flow){ int i,k; double use=0,j; if (v==n) return flow; for (k=fi[v];k;k=ne[k]) if (bz[la[k]]+1==bz[v] && Abs(va[k])>eps){ j=gap(la[k],min(va[k],flow-use)); use+=j; va[k]-=j; va[k^1]+=j; if (Abs(flow-use)<eps || bz[1]==n) return use; } if (!--card[bz[v]]) bz[1]=n; card[++bz[v]]++; return use;}
1.三个中两个return返回的都是use;
2.当use==flow使,直接返回use;
3.到达汇点,返回flow。
0 0
- 【JZOJ3215】【SDOI2013】费用流
- 【SDOI2013】费用流
- 3130: [Sdoi2013]费用流
- 【SDOI2013】【BZOJ3130】费用流
- bzoj3130【SDOI2013】费用流
- BZOJ3130 [Sdoi2013]费用流
- [bzoj3130][sdoi2013]费用流
- 【SDOI2013】bzoj3130 费用流
- 3130: [Sdoi2013]费用流
- [SDOI2013]费用流
- BZOJ 3130 [Sdoi2013] 费用流
- [题解]bzoj3130(SDOI2013)费用流
- 【BZOJ】3130: [Sdoi2013]费用流
- 【bzoj3130】 SDOI2013费用流 最大流
- 【bzoj3130】【SDOI2013】【费用流】【最大流】
- [bzoj3130][Sdoi2013]费用流 二分+最大流
- [BZOJ3130][Sdoi2013]费用流 做题笔记
- BZOJ 3130 [Sdoi2013]费用流 题解
- POJ 1852 Ants
- PAT 1075
- Crackme 23
- 四旋翼无人机
- C#IO 文件读取笔记二
- 【JZOJ3215】【SDOI2013】费用流
- Hadoop大数据系列之一---Hadoop架构原理分析
- GesturePassword
- Activity之间转场动画
- linux环境变量设置方法总结(PATH/LD_LIBRARY_PATH)
- 垂直外边距合并--CSS的Margin属性:详解margin属性
- UBUNTU 16.04安装VIVADO&&成功启动SDK
- python复习笔记[3]——字符串
- PAT甲级练习1026. Table Tennis (30)-未完成