算法步骤:

  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. 莫烦课程Batch Normalization 批标准化

    for i in range(N_HIDDEN): # build hidden layers and BN layers input_size = 1 if i == 0 else 10 fc = ...

  2. python并发爬虫利器tomorrow(一)

    tomorrow是我最近在用的一个爬虫利器,该模块属于第三方的一个模块,使用起来非常的方便,只需要用其中的threads方法作为装饰器去修饰一个普通的函数,既可以达到并发的效果,本篇将用实例来展示to ...

  3. php中heredoc的使用方法

    Heredoc技术,在正规的PHP文档中和技术书籍中一般没有详细讲述,只是提到了这是一种Perl风格的字符串输出技术.但是现在的一些论坛程序,和部分文章系统,都巧妙的使用heredoc技术,来部分的实 ...

  4. tensorflow中的boolean_mask

    将mask中所有为true的抽取出来,放到一起,这里从n维降到1维度 tensor = [[1, 2], [3, 4], [5, 6]] import numpy as np mask=np.arra ...

  5. git —— pycharm+git管理/编辑项目

    pycharm+git  管理/编辑项目 一.pycharm中配置github 二.配置git 并不是配置了GitHub就可以的.还需要配置一下Git 前提是本地中已经安装了git 三.把本地项目上传 ...

  6. thinkphp调试

    Sql调试

  7. IntelliJ IDEA + Tomcat ;On Upate Action 与 On Frame Deactivation

    On Upate Action 与 On Frame Deactivation  这两个选项的设置,依赖于 项目的部署方式 是war包 还是 exploded ,看下面的gif: 这里实在是太灵活了, ...

  8. java正则表达式(转)

    1.验证email public static void main(String[] args) { // 要验证的字符串 String str = "service@xsoftlab.ne ...

  9. CVE-2010-0248

    [CNNVD]Microsoft Internet Explorer 多个远程代码执行漏洞(CNNVD-201001-237) Microsoft Internet Explorer 6, 6 SP1 ...

  10. Windows开机自动启动pageant,方便使用ssh链接到GitHub

    按win +r,输入 shell:startup "C:\Program Files\TortoiseGit\bin\pageant.exe" "d:\GitHubPri ...