题目:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3496

大概意思:给你一个网络,有源汇,在保证最大流的情况下求下面两个问题答案

1.所有边中流量最大的边流量最小

2.所有边中流量最小的边流量最大


题解:

De了一下午啊啊,之前学的上下界网络流有问题!

对于问题一,我们二分最大流量,每次建图跑最大流,看是不是和之前一样即可

对于问题二,我们同样二分答案lim,这样每条边满足流量限制w[i]∈[lim,c[i]]

这样建图跑有源汇最大流即可.

下面是坑点

之前写的有源汇最大流都是先跑可行流然后把超级源和超级汇删掉再跑,答案还得加加减减,但是就是Wa

后来发现其实并没有那么难,在可行流的残余网络直接再跑一边最大流就是答案

感性证明如下:

因为如果可行的话超级源的所有出边都满流,这样算最大流的时候只会算到t->s的反边上,又因为原来的可行流就在这条边上,这样直接就能算出答案

别忘了输出答案*p

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
typedef long long ll;
#define N 505
#define M 400005
#define INF 0x3f3f3f3f
using namespace std;
ll Case,n,m,t,s,P,ans1,ans2,S,T,ecnt,Maxflow,l,r,u[M],v[M],c[M],mid,Maxc,lim;
ll head[N],lev[N],cur[N],du[N];
queue <ll> q;
struct adj
{
ll nxt,v,w;
} e[M];
ll read()
{
ll ret=,neg=;
char j=getchar();
for (; j>'' || j<''; j=getchar())
if (j=='-') neg=-;
for (; j>='' && j<=''; j=getchar())
ret=ret*+j-'';
return ret*neg;
}
void add(ll u,ll v,ll w)
{
e[++ecnt].v=v;e[ecnt].w=w;e[ecnt].nxt=head[u];head[u]=ecnt;
e[++ecnt].v=u;e[ecnt].w=;e[ecnt].nxt=head[v];head[v]=ecnt;
}
void init()
{
ecnt=;
memset(head,,sizeof(head));
}
bool Bfs()
{
while (!q.empty()) q.pop();
for (ll i=; i<=lim; i++)
cur[i]=head[i],lev[i]=-;
q.push(S),lev[S]=;
while (!q.empty())
{
ll u=q.front();
q.pop();
for (ll i=head[u],v; i; i=e[i].nxt)
if (lev[v=e[i].v]==- && e[i].w>)
{
q.push(v),lev[v]=lev[u]+;
if (v==T) return ;
}
}
return ;
}
ll Dfs(ll u,ll flow)
{
if (u==T) return flow;
ll ret=,delta;
for (ll &i=cur[u],v; i; i=e[i].nxt)
if (e[i].w> && lev[v=e[i].v]==lev[u]+)
{
delta=Dfs(v,min(e[i].w,flow-ret));
if (delta)
{
e[i].w-=delta;
e[i^].w+=delta;
ret+=delta;
if (ret==flow) break;
}
}
return ret;
}
ll getG(ll lim)
{
ll sum=,tmp=;
init();
add(t,s,INF);S=n+,T=n+;
memset(du,,sizeof(du));
for (ll i=; i<=m; i++)
if (c[i]-lim<) return -;
else add(u[i],v[i],c[i]-lim),du[u[i]]-=lim,du[v[i]]+=lim;
for (ll i=; i<=n; i++)
{
if (du[i]>) add(S,i,du[i]),sum+=du[i];
if (du[i]<) add(i,T,-du[i]);
}
while (Bfs()) tmp+=Dfs(S,INF);
if (tmp!=sum) return -;
tmp=;S=s;T=t;
while (Bfs()) tmp+=Dfs(S,INF);
return tmp;
}
int main()
{
Case=read();
while (Case--)
{
n=read(),m=read(),s=read(),t=read(),P=read();
init();
S=++s;T=++t;
Maxflow=Maxc=l=;
lim=n+;
for (ll i=; i<=m; i++)
u[i]=read(),v[i]=read(),c[i]=read(),add(++u[i],++v[i],c[i]),r=Maxc=max(Maxc,c[i]);
while (Bfs()) Maxflow+=Dfs(S,INF);
while (l<r)
{
init();
ll mid=l+r>>,tmp=;
for (ll i=; i<=m; i++) add(u[i],v[i],min(c[i],mid));
while (Bfs()) tmp+=Dfs(S,INF);
if (tmp==Maxflow) r=mid;
else l=mid+;
}
ans1=l;l=;r=Maxc;
while (l<r)
{
ll mid=l+r+>>,tmp=;
if (getG(mid)==Maxflow) l=mid;
else r=mid-;
}
ans2=l;
printf("%lld %lld\n",1ll*ans1*P,1ll*ans2*P);
}
return ;
}

ZOJ 3496 Assignment | 二分+有上下界网络流的更多相关文章

  1. [zoj] 3496 Assignment || 有源汇上下界最大流

    原题 贴个博客吧 #include<cstdio> #include<algorithm> #include<cstring> #define N 510 #def ...

  2. 【上下界网络流 二分】bzoj2406: 矩阵

    感觉考试碰到上下界网络流也还是写不来啊 Description Input 第一行两个数n.m,表示矩阵的大小. 接下来n行,每行m列,描述矩阵A. 最后一行两个数L,R. Output 第一行,输出 ...

  3. BZOJ 2406 二分+有上下界的网络流判定

    思路: 求出每行的和  sum_row 每列的和   sum_line 二分最后的答案mid S->i  流量[sum_row[i]-mid,sum_row[i]+mid] i->n+j ...

  4. ZOJ Problem Set - 3229 Shoot the Bullet 【有上下界网络流+流量输出】

    题目:problemId=3442" target="_blank">ZOJ Problem Set - 3229 Shoot the Bullet 分类:有源有汇 ...

  5. 【有上下界网络流】【ZOJ】2314 Reactor Cooling

    [算法]有上下界网络流-无源汇(循环流) [题解]http://www.cnblogs.com/onioncyc/p/6496532.html //未提交 #include<cstdio> ...

  6. hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )

    题意:有n个点和m条有向边构成的网络.每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到 ...

  7. ACM-ICPC 2018 沈阳赛区网络预赛 F Fantastic Graph(贪心或有源汇上下界网络流)

    https://nanti.jisuanke.com/t/31447 题意 一个二分图,左边N个点,右边M个点,中间K条边,问你是否可以删掉边使得所有点的度数在[L,R]之间 分析 最大流不太会.. ...

  8. 算法笔记--最大流和最小割 && 最小费用最大流 && 上下界网络流

    最大流: 给定指定的一个有向图,其中有两个特殊的点源S(Sources)和汇T(Sinks),每条边有指定的容量(Capacity),求满足条件的从S到T的最大流(MaxFlow). 最小割: 割是网 ...

  9. POJ 2396 Budget(有源汇上下界网络流)

    Description We are supposed to make a budget proposal for this multi-site competition. The budget pr ...

随机推荐

  1. Python序列删除重复数据

    ## 对于列表来说,若不保持原有顺序,可以直接转换为set删除重复数据 nums = [1,2,32,2,2,4,3,2,3,42] nums = list(set(nums)) print(nums ...

  2. POJ1985 树的直径(BFS

    Cow Marathon   Description After hearing about the epidemic of obesity in the USA, Farmer John wants ...

  3. LeetCode算法1—— 两数之和

    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...

  4. Linux 之vi与vim

    vi 三种模式: 『一般模式』: 光标 『编辑模式』:i,o,a,r 『指令列命令模式』「:/ ?」 例子: 1. 请在/tmp 这个目录下建立一个名为vitest 的目录: 2. 将/etc/man ...

  5. itop-4412开发板学习-内核信号量

    1. 翻翻书看下,linux提供两种信号量,内核信号量,由内核控制路径使用,System V IPC信号量,由用户态进程使用.下面的就是内核部分的信号量.内核信号量类似于自旋锁,当锁关闭着时,不允许内 ...

  6. EF报错“EntityValidationErrors”

          在使用EF更新实体的时候报错,显示界面如下:       点击查看详情:        在查看详细的窗体中,EntityValidationErrors里面的也看不到具体的错误原因.在网上 ...

  7. jmeter结合autoit操作windows程序

    需求: 模拟操作下图软件的控件,如拨号和挂机. 1. 下载安装好autoit后,打开finder tool,使用查找工具定位到要模拟操作的控件上,如图: 2.在finder tool中的control ...

  8. 「暑期训练」「Brute Force」 Restoring Painting (CFR353D2B)

    题意 给定一定条件,问符合的矩阵有几种. 分析 见了鬼了,这破题谁加的brute force的标签,素质极差.因为范围是1e5,那你平方(枚举算法)的复杂度必然爆. 然后你就会思考其中奥妙无穷的数学规 ...

  9. python 基础篇 16 递归和二分数查找与编码补充回顾

    编码回顾补充: 回顾编码问题:        编码相当于密码本,关系到二进制与看懂的文字的的对应关系.    最早期的密码本:        ascii码:只包含英文字母,数字,特殊字符.       ...

  10. P4332三叉神经树

    题面 \(Solution\) 通过模拟,我们会发现每次修改 \(x\),只会改变从 \(x\) 向上一段连续的链的输出. 例如将 \(x\) 点从 \(0\) 改为 \(1,\) 那么它会影响从它向 ...