sgu 176 上下界网络流最小可行流带输出方案
算法步骤:
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 上下界网络流最小可行流带输出方案的更多相关文章
- zoj 3229 上下界网络最大可行流带输出方案
收获: 1. 上下界网络流求最大流步骤: 1) 建出无环无汇的网络,并看是否存在可行流 2) 如果存在,那么以原来的源汇跑一次最大流 3) 流量下界加上当前网络每条边的流量就是最大可行流了. 2. 输 ...
- hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )
题意:有n个点和m条有向边构成的网络.每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到 ...
- POJ 2396 Budget (上下界网络流有源可行流)
转载: http://blog.csdn.net/axuan_k/article/details/47297395 题目描述: 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表 ...
- ZOJ2314 Reactor Cooling(无源汇流量有上下界网络的可行流)
题目大概说一个核反应堆的冷却系统有n个结点,有m条单向的管子连接它们,管子内流量有上下界的要求,问能否使液体在整个系统中循环流动. 本质上就是求一个无源汇流量有上下界的容量网络的可行流,因为无源汇的容 ...
- ZOJ 1314 Reactor Cooling | 上下界无源汇可行流
ZOJ 1314 Reactor Cooling | 上下界无源汇可行流 题意 有一个网络,每条边有流量的上界和下界,求一种方案,让里面的流可以循环往复地流动起来. 题解 上下界无源汇可行流的模型: ...
- POJ2396 Budget(有源汇流量有上下界网络的可行流)
题目大概给一个有n×m个单元的矩阵,各单元是一个非负整数,已知其每行每列所有单元的和,还有几个约束条件描述一些单元是大于小于还是等于某个数,问矩阵可以是怎样的. 经典的流量有上下界网络流问题. 把行. ...
- hdu4940 有上下界的无源可行流判断
题意: 给你一个强连通图,然后问你是否可以找到任意满足条件的集合S,S是非空集合,T是S的补集,满足sum(D[i ,j]) <= sum(D[j,i] + B[j,i]) i属于S ...
- sgu 194 上下界网络流可行流判定+输出可行流
#include <cstdio> #include <cstring> #define min(a,b) ((a)<(b)?(a):(b)) #define oo 0x ...
- [BZOJ2502]清理雪道 有上下界网络流(最小流)
2502: 清理雪道 Time Limit: 10 Sec Memory Limit: 128 MB Description 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场 ...
随机推荐
- JDK1.8源码TreeMap
基于红黑树(Red-Black tree)的 NavigableMap 实现:键的排序由构造方法决定:自然排序,Comparator排序:非线程安全(仅改变与现有键关联的值不是结构上的修改):线程安全 ...
- Linux XOR.DDoS样本取证特征与清除
一.取证特征 1)获取进程ID 使用top命令,查看占用内存率最高的十位随机名称进程名(示例:进程名pygdykcrqf) 2)获取进程对应路径 Linux 在启动一个进程时,系统会在/proc下创建 ...
- jenkins 和 git 的每日构建
没有太难的技术含量,只要按照步骤操作就可以成功 step 1:全局工具配置git.exe 首先,登录 Jenkins ,在首页找到 “系统管理 -> Global Tool Configurat ...
- ASP.NET Web Api OwinSelfHost Restful 使用
一.前言 总结一下什么是RESTful架构: (1)每一个URI代表一种资源: (2)客户端和服务器之间,传递这种资源的某种表现层: (3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现&q ...
- MyBatis3-实现MyBatis分页
此文章中的例子是沿用上一篇文章http://www.cnblogs.com/EasonJim/p/7055499.html的Spring MVC集成的例子改装的. MyBatis分页有以下方式实现: ...
- 16/11/22_plsql
1.数据类型: char 固定长度,varchar 字符长度按照实际长度, varchar2 字符均存储2个字节, nvarchar 按照Unicode存储.number(m,n)总长度m,小数 n. ...
- 如何阻止点击scrollviewer里面的单位内容时,自动滚动
<Style TargetType="{x:Type ListBoxItem}"> <Setter Property="FocusVisualStyle ...
- xcode7 创建pch文件
1.打开xcode 7.2 项目,在屏幕顶端的工具栏,选择File>New>File..>iOS>Other>PCH File,点击"next"下一步 ...
- GreenPlum学习笔记:create table创建表
二维表同样是GP中重要的存储数据对象,为了更好的支持数据仓库海量数据的访问,GP的表可以分成: 面向行存储的普通堆积表 面向列存储的AOT表(append only table) 当然AOT表也可以是 ...
- CF 586A 找1的个数和101的个数
Sample test(s) input 50 1 0 1 1 output 4 input 71 0 1 0 0 1 0 output 4 input 10 output 0 # include & ...