算法步骤:

  1. 先将原图像最大可行流那样变换,唯一不同的是不加dst->src那条边来将它变成无源无汇的网络流图.直接跑一边超级源到超级汇的最大流.

  2. 加上刚才没有加上的那条边p

  3. 再跑一遍超级源汇之间的最大流,p的流量就是我们要求的最小可行流流量(等于其反向边的"容量")

收获:

  1. 最大可行流和最小可行流,当我们把其残量网络求出来后,其流量就是dst->src的残量.

    每条边在此时的流量 = 流量下界 + 转换后对应边的流量

 #include <cstdio>
#include <cassert>
#include <cstring>
#define min(a,b) ((a)<(b)?(a):(b))
#define oo 0x3f3f3f3f
#define N 110
#define M N*N 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 ) {
this->n = n;
memset( head, -, sizeof(head) );
etot = ;
}
void adde( int i, int u, int v, int f ) {
info[etot]=i, flow[etot]=f, dest[etot]=v, next[etot]=head[u]; head[u]=etot++;
info[etot]=, flow[etot]=, dest[etot]=u, next[etot]=head[v]; 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 s, int t ) {
int f = ;
src = s, dst = t;
while( bfs() ) {
memcpy( cur, head, sizeof(cur) );
f += dfs(src,oo);
}
return f;
}
}dinic;
struct Btop {
int n;
int head[N], dest[M], bval[M], tval[M], next[M], info[M], etot;
int sumi[N], sumo[N];
void init( int n ) {
etot = ;
memset( head, -, sizeof(head) );
this->n = n;
}
void adde( int i, int u, int v, int b, int t ) {
info[etot]=i, bval[etot]=b, tval[etot]=t;
dest[etot]=v, next[etot]=head[u];
sumi[v]+=b, sumo[u]+=b;
head[u] = etot++;
}
int minflow( int src, int dst ) {
int ss=n+, tt=n+, sum;
dinic.init( n+ );
for( int u=; u<=n; u++ )
for( int t=head[u]; t!=-; t=next[t] ) {
int v=dest[t];
dinic.adde( info[t], u, v, tval[t]-bval[t] );
}
sum = ;
for( int u=; u<=n; u++ ) {
if( sumi[u]>sumo[u] ) {
dinic.adde( , ss, u, sumi[u]-sumo[u] );
sum += sumi[u]-sumo[u];
} else if( sumo[u]>sumi[u] ) {
dinic.adde( , u, tt, sumo[u]-sumi[u] );
}
}
int f = ;
f += dinic.maxflow(ss,tt);
dinic.adde( , dst, src, oo );
f += dinic.maxflow(ss,tt);
if( f!=sum ) return -;
int eid = dinic.etot-;
return dinic.flow[eid^];
}
}btop; int n, m;
int ans[M], tot; int main() {
scanf( "%d%d", &n, &m );
btop.init( n );
for( int i=,u,v,z,c; i<=m; i++ ) {
scanf( "%d%d%d%d", &u, &v, &z, &c );
if( c== ) btop.adde( i, u, v, z, z );
else btop.adde( i, u, v, , z );
ans[i] = c ? z : ;
}
int minf = btop.minflow(,n);
if( minf==- ) {
printf( "Impossible\n" );
return ;
}
for( int e=; e<dinic.etot; e++ ) {
int i=dinic.info[e];
if( i ) ans[i] += dinic.flow[e^];
}
printf( "%d\n", minf );
for( int i=; i<=m; i++ )
printf( "%d ", ans[i] );
printf( "\n" );
}

sgu 176 上下界网络流最小可行流带输出方案的更多相关文章

  1. zoj 3229 上下界网络最大可行流带输出方案

    收获: 1. 上下界网络流求最大流步骤: 1) 建出无环无汇的网络,并看是否存在可行流 2) 如果存在,那么以原来的源汇跑一次最大流 3) 流量下界加上当前网络每条边的流量就是最大可行流了. 2. 输 ...

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

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

  3. POJ 2396 Budget (上下界网络流有源可行流)

    转载: http://blog.csdn.net/axuan_k/article/details/47297395 题目描述: 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表 ...

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

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

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

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

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

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

  7. hdu4940 有上下界的无源可行流判断

    题意:       给你一个强连通图,然后问你是否可以找到任意满足条件的集合S,S是非空集合,T是S的补集,满足sum(D[i ,j]) <= sum(D[j,i] + B[j,i]) i属于S ...

  8. sgu 194 上下界网络流可行流判定+输出可行流

    #include <cstdio> #include <cstring> #define min(a,b) ((a)<(b)?(a):(b)) #define oo 0x ...

  9. [BZOJ2502]清理雪道 有上下界网络流(最小流)

    2502: 清理雪道 Time Limit: 10 Sec  Memory Limit: 128 MB Description        滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场 ...

随机推荐

  1. https://www.yunpanjingling.com/

    https://www.yunpanjingling.com/ 账号  kein20 passwd a1234

  2. Git管理本地代码(一)【转】

    转自:http://blog.csdn.net/weihan1314/article/details/8677800 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   安 ...

  3. TcxScheduler的使用2

    DevExpress 行事历(Scheduler)的常用属性.事件和方法 参考资料来源:附带的ExpressScheduler 2  Demo, 如想了解更多可以查看Demo. 一.TcxSchedu ...

  4. ASP.NET 实现Base64文件流下载PDF

    因为业务需要调用接口获取的是 Base64文件流 需要提供给客户下载PDF文档 源码部分借鉴网上,具体地址忘记了. //Base64文件流 byte[] buffer = Convert.FromBa ...

  5. Ubuntu下软件安装方式、PATH配置、查找安装位置

    Ubuntu 18.04, 安装方式 目前孤知道的Ubuntu下安装软件方式有3种(命令): 1.make 2.apt/apt-get 3.dpkg 方式1基于软件源码安装,需要经历配置(可选).编译 ...

  6. JsRender 前端渲染模板常用API学习

    JsRender 常用API 1. $.templates() $.templates()方法是用来注册或编译模板的,使用的情况有以下几种. 把html字符串编译编译成模板 获取使用script标签声 ...

  7. vue 递归组件

    如果你的项目里面的数据结构是一个树状的数据结构 然后递归组件是一个很好的一个解决你这个数据结构的一个方式 就是组件内部调用自身 tree.vue里面直接tree-node <tree-node& ...

  8. springMVC源码分析--HttpMessageConverter参数read操作(二)

    上一篇博客springMVC源码分析--HttpMessageConverter数据转化(一)中我们简单介绍了一下HttpMessageConverter接口提供的几个方法,主要有以下几个方法: (1 ...

  9. 20165203《Java程序设计》第四周学习总结

    教材学习内容总结 第5章 子类与继承 子类的继承性 子类和父类在同一包中的继承性:子类继承父类中不是private的成员变量和方法作为自己的成员变量和方法 子类和父类不在同一包中的继承性:子类只继承父 ...

  10. CF GYM100548 (相邻格子颜色不同的方案数 2014西安现场赛F题 容斥原理)

    n个格子排成一行,有m种颜色,问用恰好k种颜色进行染色,使得相邻格子颜色不同的方案数. integers n, m, k (1 ≤n, m ≤ 10^9, 1 ≤ k ≤ 10^6, k ≤ n, m ...