zoj 3229 上下界网络最大可行流带输出方案
收获:
1. 上下界网络流求最大流步骤:
1) 建出无环无汇的网络,并看是否存在可行流
2) 如果存在,那么以原来的源汇跑一次最大流
3) 流量下界加上当前网络每条边的流量就是最大可行流了.
2. 输出方案:
可以把边的位置信息一起存在边表中,求完最大流后遍历一下边,把信息更新过去.
#include <cstdio>
#include <cstring>
#define min(a,b) ((a)<(b)?(a):(b))
#define oo 0x3f3f3f3f
#define N 1500
#define M 500000 struct Dinic {
int n, src, dst;
int head[N], dest[M], flow[M], next[M], info[M][], etot;
int cur[N], dep[N], qu[N], bg, ed;
void init( int n, int src, int dst ) {
this->n = n;
this->src = src;
this->dst = dst;
etot = ;
memset( head, -, sizeof(head) );
}
void adde( int i, int j, int u, int v, int f ) {
next[etot]=head[u],flow[etot]=f,dest[etot]=v,info[etot][]=i,info[etot][]=j; head[u]=etot++;
next[etot]=head[v],flow[etot]=,dest[etot]=u,info[etot][]=-,info[etot][]=-; head[v]=etot++;
}
bool bfs() {
memset( dep, , sizeof(dep) );
qu[bg=ed=] = src;
dep[src] = ;
while( bg<=ed ) {
int u=qu[bg++];
for( int t=head[u]; t!=-; t=next[t] ) {
int v=dest[t], f=flow[t];
if( f && !dep[v] ) {
dep[v] = dep[u]+;
qu[++ed] = v;
}
}
}
return dep[dst];
}
int dfs( int u, int a ) {
if( u==dst || a== ) return a;
int remain=a, past=, na;
for( int &t=cur[u]; t!=-; t=next[t] ) {
int v=dest[t], &f=flow[t], &vf=flow[t^];
if( f && dep[v]==dep[u]+ && (na=dfs(v,min(remain,f))) ) {
f -= na;
vf += na;
remain -= na;
past += na;
if( !remain ) break;
}
}
return past;
}
int maxflow() {
int f=;
while( bfs() ) {
memcpy( cur, head, sizeof(cur) );
f += dfs(src,oo);
}
return f;
}
}D;
struct Btop {
int n;
int head[N], dest[M], bval[M], tval[M], next[M], info[M][], etot;
int si[N], so[N];
void init( int n ) {
this->n = n;
etot = ;
memset( head, -, sizeof(head) );
memset( si, , sizeof(si) );
memset( so, , sizeof(so) );
}
void adde( int i, int j, int u, int v, int b, int t ) {
next[etot]=head[u],tval[etot]=t,bval[etot]=b,dest[etot]=v;
info[etot][]=i, info[etot][]=j;
si[v] += b, so[u] += b;
head[u]=etot++;
}
bool ok() {
int src=n+, dst=n+;
D.init( dst, src, dst );
for( int u=; u<=n; u++ )
for( int t=head[u]; t!=-; t=next[t] ) {
int v=dest[t];
D.adde( info[t][], info[t][], u, v, tval[t]-bval[t] );
}
int sum = ;
for( int u=; u<=n; u++ ) {
if( si[u]>so[u] ) {
D.adde( -, -, src, u, si[u]-so[u] );
sum += si[u]-so[u];
} else if( so[u]>si[u] ) {
D.adde( -, -, u, dst, so[u]-si[u] );
}
}
return sum==D.maxflow();
}
}B; int n, m;
int c[];
int ans[][], tot; int main() {
while( scanf( "%d%d", &n, &m ) == ) {
int src=n+m+, dst=src+;
B.init(dst);
for( int i=,g; i<=m; i++ ) {
scanf( "%d", &g );
B.adde( -, -, n+i, dst, g, oo );
}
memset( ans, , sizeof(ans) );
tot = ;
for( int i=,d; i<=n; i++ ) {
scanf( "%d%d", c+i, &d );
B.adde( -, -, src, i, , d );
for( int j=,t,l,r; j<=c[i]; j++ ) {
scanf( "%d%d%d", &t, &l, &r );
t++;
B.adde( i, j, i, n+t, l, r );
ans[i][j] = l;
tot += l;
}
}
B.adde( -, -, dst, src, , oo );
bool ok = B.ok();
if( !ok ) {
printf( "-1\n" );
} else {
D.src=src;
D.dst=dst;
D.maxflow();
for( int t=; t<D.etot; t++ ) {
int i=D.info[t][], j=D.info[t][];
if( ~i && ~j ) {
ans[i][j] += D.flow[t^];
tot += D.flow[t^];
}
}
printf( "%d\n", tot );
for( int i=; i<=n; i++ )
for( int j=; j<=c[i]; j++ )
printf( "%d\n", ans[i][j] );
}
printf( "\n" );
}
}
zoj 3229 上下界网络最大可行流带输出方案的更多相关文章
- sgu 176 上下界网络流最小可行流带输出方案
算法步骤: 1. 先将原图像最大可行流那样变换,唯一不同的是不加dst->src那条边来将它变成无源无汇的网络流图.直接跑一边超级源到超级汇的最大流. 2. 加上刚才没有加上的那条边p 3. 再 ...
- POJ2396 Budget(有源汇流量有上下界网络的可行流)
题目大概给一个有n×m个单元的矩阵,各单元是一个非负整数,已知其每行每列所有单元的和,还有几个约束条件描述一些单元是大于小于还是等于某个数,问矩阵可以是怎样的. 经典的流量有上下界网络流问题. 把行. ...
- ZOJ2314 Reactor Cooling(无源汇流量有上下界网络的可行流)
题目大概说一个核反应堆的冷却系统有n个结点,有m条单向的管子连接它们,管子内流量有上下界的要求,问能否使液体在整个系统中循环流动. 本质上就是求一个无源汇流量有上下界的容量网络的可行流,因为无源汇的容 ...
- ZOJ 1314 Reactor Cooling | 上下界无源汇可行流
ZOJ 1314 Reactor Cooling | 上下界无源汇可行流 题意 有一个网络,每条边有流量的上界和下界,求一种方案,让里面的流可以循环往复地流动起来. 题解 上下界无源汇可行流的模型: ...
- HDU3157 Crazy Circuits(有源汇流量有上下界网络的最小流)
题目大概给一个电路,电路上有n+2个结点,其中有两个分别是电源和负载,结点们由m个单向的部件相连,每个部件都有最少需要的电流,求使整个电路运转需要的最少电流. 容量网络的构建很容易,建好后就是一个有源 ...
- hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )
题意:有n个点和m条有向边构成的网络.每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到 ...
- BZOJ 3876 支线剧情 有源汇有上下界最小费用可行流
题意: 给定一张拓扑图,每条边有边权,每次只能从第一个点出发沿着拓扑图走一条路径,求遍历所有边所需要的最小边权和 分析: 这道题乍一看,可能会想到什么最小链覆盖之类的,但是仔细一想,会发现不行,一是因 ...
- BZOJ 2055 80人环游世界 有上下界最小费用可行流
题意: 现在有这么一个m人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家. 因为他们主要分布在东方,所以他们只朝西方进军.设从东方到西方的每一个国家的编号依次为1...N.假若第 ...
- ZOJ3229 Shoot the Bullet(有源汇流量有上下界网络的最大流)
题目大概说在n天里给m个女孩拍照,每个女孩至少要拍Gi张照片,每一天最多拍Dk张相片且都有Ck个拍照目标,每一个目标拍照的张数要在[Lki, Rki]范围内,问最多能拍几张照片. 源点-天-女孩-汇点 ...
随机推荐
- Sicily 1211. 商人的宣传
题目链接:http://soj.me/1211 Description Bruce是K国的商人,他在A州成立了自己的公司,这次他的公司生产出了一批性能很好的产品,准备宣传活动开始后的第L天到达B州进行 ...
- 26 About the go command go命令行
About the go command go命令行 Motivation Configuration versus convention Go's conventions Getting star ...
- Ubuntu 18.04安装MongoDB 4.0(社区版)
Ubuntu 18.04(虚拟机VirtualBox上),MongoDB 4.0, 听室友说,23点有世界杯决赛呢!可是,孤要写博文的啊!以记录这忙乱的下午和晚间成功安装了一个软件到Linux上.—— ...
- mac下PHPStorm2018.2破解教程
1.首先安装phpstorm 2.下载JetbrainsCrack-3.1-release-enc.jar然后把这个文件放入安装phpstorm/contents/lib目录下 3.用文本编辑器打开p ...
- Go 的package
一.包的一些基本的概念 1.在同一个目录下的所有go文件中,只能有一个main函数.如果存在多个main函数,则在编译的时候会报错 那么,在同一个目录下的两个go文件究竟是什么关系? 为什么会彼此影响 ...
- java基础29 迭代器 listIterator() 及各种遍历集合的方法
listIterator() 迭代器包含了 Iterator() 迭代器中的所有方法. 1.ListIterator的常用方法 hasPrevious() :判断是否还有上一个元素,有则返回true ...
- Centos简介
Centos作为主流的一种Linux操作系统,以后项目中,比如后期Redis,以及部署一些项目,会把Centos作为服务器操作系统,我们选用Centos,主要是免费,以及稳定. Centos详细介绍, ...
- VS2015的对象浏览器的使用
用vs开发这么久了,还是第一次用上对象浏览器的功能,第一次用有一点懵逼,记录一下. 这个图标是项目 这是代表类,下面可以展开看到基类 在右边可以看到这个类的方法和成员 这个代表结构体 同样的右边显示成 ...
- 微信小程序-视频教程-百度云-下载
链接: https://pan.baidu.com/s/16WGL3whutozx-UXqsDPhhA 提取码: 关注公众号[GitHubCN]回复获取 什么是微信小程序?小程序是一种不需要下载安 ...
- HBase(一)HBase入门简介
一 HBase 的起源 HBase 的原型是 Google 的 BigTable 论文,受到了该论文思想的启发,目前作为 Hadoop 的子项目来开发维护,用于支持结构化的数据存储. Apache H ...