收获:

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 上下界网络最大可行流带输出方案的更多相关文章

  1. sgu 176 上下界网络流最小可行流带输出方案

    算法步骤: 1. 先将原图像最大可行流那样变换,唯一不同的是不加dst->src那条边来将它变成无源无汇的网络流图.直接跑一边超级源到超级汇的最大流. 2. 加上刚才没有加上的那条边p 3. 再 ...

  2. POJ2396 Budget(有源汇流量有上下界网络的可行流)

    题目大概给一个有n×m个单元的矩阵,各单元是一个非负整数,已知其每行每列所有单元的和,还有几个约束条件描述一些单元是大于小于还是等于某个数,问矩阵可以是怎样的. 经典的流量有上下界网络流问题. 把行. ...

  3. ZOJ2314 Reactor Cooling(无源汇流量有上下界网络的可行流)

    题目大概说一个核反应堆的冷却系统有n个结点,有m条单向的管子连接它们,管子内流量有上下界的要求,问能否使液体在整个系统中循环流动. 本质上就是求一个无源汇流量有上下界的容量网络的可行流,因为无源汇的容 ...

  4. ZOJ 1314 Reactor Cooling | 上下界无源汇可行流

    ZOJ 1314 Reactor Cooling | 上下界无源汇可行流 题意 有一个网络,每条边有流量的上界和下界,求一种方案,让里面的流可以循环往复地流动起来. 题解 上下界无源汇可行流的模型: ...

  5. HDU3157 Crazy Circuits(有源汇流量有上下界网络的最小流)

    题目大概给一个电路,电路上有n+2个结点,其中有两个分别是电源和负载,结点们由m个单向的部件相连,每个部件都有最少需要的电流,求使整个电路运转需要的最少电流. 容量网络的构建很容易,建好后就是一个有源 ...

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

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

  7. BZOJ 3876 支线剧情 有源汇有上下界最小费用可行流

    题意: 给定一张拓扑图,每条边有边权,每次只能从第一个点出发沿着拓扑图走一条路径,求遍历所有边所需要的最小边权和 分析: 这道题乍一看,可能会想到什么最小链覆盖之类的,但是仔细一想,会发现不行,一是因 ...

  8. BZOJ 2055 80人环游世界 有上下界最小费用可行流

    题意: 现在有这么一个m人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家.    因为他们主要分布在东方,所以他们只朝西方进军.设从东方到西方的每一个国家的编号依次为1...N.假若第 ...

  9. ZOJ3229 Shoot the Bullet(有源汇流量有上下界网络的最大流)

    题目大概说在n天里给m个女孩拍照,每个女孩至少要拍Gi张照片,每一天最多拍Dk张相片且都有Ck个拍照目标,每一个目标拍照的张数要在[Lki, Rki]范围内,问最多能拍几张照片. 源点-天-女孩-汇点 ...

随机推荐

  1. linux音频alsa-uda134x驱动文档阅读之一转自http://blog.csdn.net/wantianpei/article/details/7817293

    前言 目前,linux系统常用的音频驱动有两种形式:alsa oss alsa:现在是linux下音频驱动的主要形式,与简单的oss兼容.oss:过去的形式而我们板子上的uda1341用的就是alsa ...

  2. juery下拉刷新,ajax请求,div加载更多元素(一)

    ;//设置当前页数 var flag=true; //滑动加载 $(function(){ var winH = $(window).height(); //页面可视区域高度 $(window).sc ...

  3. HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V ...

  4. haproxy支持的负载均衡算法详解

    目前haproxy支持的负载均衡算法有如下8种: 1.roundrobin 表示简单的轮询,每个服务器根据权重轮流使用,在服务器的处理时间平均分配的情况下这是最流畅和公平的算法.该算法是动态的,对于实 ...

  5. mysql高可用架构 -> MHA主从复制-03

    GTID复制技术说明 GTID的全称为 global transaction identifier ,可以翻译为全局事务标示符,GTID在原始master上的事务提交时被创建.GTID需要在全局的主- ...

  6. 26 About the go command go命令行

    About the go command  go命令行 Motivation Configuration versus convention Go's conventions Getting star ...

  7. Java项目打war包的方法

    我们可以运用DOS命令来手工打war包: 首先,打开DOS命令行,敲入“jar”,我们发现它提示不是内部或外部的命令这样的错误,这时八成是你的JAVA环境没有配置好,我们可以用JAVA_HOME方式或 ...

  8. 浅谈js设计模式之策略模式

    策略模式有着广泛的应用.本节我们就以年终奖的计算为例进行介绍. 很多公司的年终奖是根据员工的工资基数和年底绩效情况来发放的.例如,绩效为 S的人年终奖有 4倍工资,绩效为 A的人年终奖有 3倍工资,而 ...

  9. 序列化 json和pickle

    序列化 1. 什么叫序列化 将原本的字典.列表等内容转换成一个字符串的过程就叫做序列化. 2.  json dumps loads    一般对字典和列表序列化 dump load       一般对 ...

  10. Luogu P1160 【队列安排】

    详细的链表讲解 很明显的一个链表裸题 和普通的链表有一个区别就是这个题 可以O(1)插入,O(1)查询 然后我们为了方便,采用双向链表,定义s.f作为指针数组 更详细的解释见代码 #include&l ...