题目:

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. over开窗函数的用法

    over(partition by c1.pmid,d1.type,e1.objid  order by e1.objid ) pinum 先根据字段排序,pinum.在取第一条数据and p1.pi ...

  2. Mysql基础3-数据操作语言DML-数据查询语言DQL

    主要: 数据操作语言DML 数据查询语言DQL 数据操作语言DML DML: Data Mutipulation Language 插入数据(增) 一般插入数据形式 1)形式1: insert [in ...

  3. hive 学习系列之七 hive 常用数据清洗函数

    1,case when 的利用,清洗诸如评分等的内容,用例如下. case when new.comment_grade = '五星商户' then 50 when new.comment_grade ...

  4. webug学习(1)

    webug的题目,比较简单,拿来巩固一哈. 1. 一看就知道是注入漏洞了,啥也不说sqlmap直接开炮. 先-u 之后-u 网址 --current-db 获取当前网址的数据库 所以当前数据库就是 p ...

  5. 解决MySQL server has gone away问题的两种有效办法

    最近做网站有一个站要用到WEB网页采集器功能,当一个PHP脚本在请求URL的时候,可能这个被请求的网页非常慢慢,超过了mysql的 wait-timeout时间,然后当网页内容被抓回来后,准备插入到M ...

  6. Python3 os模块&sys模块&hashlib模块

    ''' os模块 非常重要的模块 ''' import os # print(os.getcwd()) # 获取当前工作目录 # os.chdir(r'路径名') # 改变当前工作目录 # print ...

  7. 【MySql】mysql 慢日志查询工具之mysqldumpslow

      当使用--log-slow-queries[=file_name]选项启动时,mysqld写一个包含所有执行时间超过long_query_time秒的SQL语句的日志文件.获得初使表锁定的时间不算 ...

  8. mysql 函数以及操作总结

    1. 拼接 concat(参数1,参数2,.. ,参数)  实现将多个字符串拼接到一起 要批量修改一个字段值   字段值又是复杂的sql 计算得来   通过查询字段值 和 修改的条件fundId(这是 ...

  9. Hibernate-ORM:15.Hibernate中的Criteria查询

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客讲师Hibernate中的Criteria查询! 一,Criteria简介: 刚接触Hibernate ...

  10. 环境变量 - Maven

    Linux 1. 备份并编辑配置文件 # cp /etc/profile /etc/profile.bak # vi /etc/profile 2. 设置Maven环境变量 export MAVEN_ ...