上下界网络流

2021.9.3

无源汇上下界可行流

之前的最大流讨论一般为有源无下届情况,那么无源汇有上下界可行流应如何求解?

首先要做的是消除下边界,应如何做?在有下届情形下,流网络中的任意一条边的可行流应满足fmin(u,v)≤c(u,v)≤fmax(u,v)fmin(u, v) \le c(u, v) \le fmax(u, v)fmin(u,v)≤c(u,v)≤fmax(u,v),由此可变换公式得0≤c(u,v)−fmin(u,v)≤fmax(u,v)−fmin(u,v)0 \le c(u, v) - fmin(u, v) \le fmax(u, v) - fmin(u, v)0≤c(u,v)−fmin(u,v)≤fmax(u,v)−fmin(u,v),此时,构建的流网络中边的下届均为000.

但是,此时引入了新的问题:流量是否守恒?绝大部分情况下,不守恒。新网络中,由上方公式构建的可行流,排除下届后守恒,但是有如下情形:设当前点为iii,入边为jjj,出边为kkk,若∑jj⊂edge[i]fmin(j)!=∑kk⊂edge[i]fmin(k)\sum_{j}^{j \subset edge[i]}{fmin(j)} != \sum_{k}^{k \subset edge[i]}{fmin(k)}∑jj⊂edge[i]​fmin(j)!=∑kk⊂edge[i]​fmin(k) ,则此时总流量不守恒。

如何解决?已知本题类型为无源汇,因此每个结点,都可理解为一个源头。但不能直接从结点加入流量,若直接从结点算作无限流量,则无法保证整条路中的流量守恒。

此时可加入一个虚拟源点SSS和一个虚拟汇点TTT,当一个结点i的入边下届小于出边下届,便从源点SSS向i连接一条最大流量为∑jj⊂edge[i]fmin(j)−∑kk⊂edge[i]fmin(k)\sum_{j}^{j \subset edge[i]}{fmin(j)} - \sum_{k}^{k \subset edge[i]}{fmin(k)}∑jj⊂edge[i]​fmin(j)−∑kk⊂edge[i]​fmin(k) 的边,当iii的入边下届大于出边下届,便从iii向TTT连接一条最大流量为∑kk⊂edge[i]fmin(k)−∑jj⊂edge[i]fmin(j)\sum_{k}^{k \subset edge[i]}{fmin(k)} - \sum_{j}^{j \subset edge[i]}{fmin(j)}∑kk⊂edge[i]​fmin(k)−∑jj⊂edge[i]​fmin(j) 的边,由此保证了整个网络的流量守恒−-−流量中每条边的流量之和等于每个结点产生的流量,此时可把每个点产生的流量转移到我们自行添加的虚拟源点之上。

代码

cin >> n >> m;
S = 0, T = n + 1;
memset(head, -1, sizeof head);
for (int i = 0; i < m; i++) {int a, b, c, d;cin >> a >> b >> c >> d;add(a, b, c, d);A[a] -= c, A[b] += c;
}
int tot = 0;
for (int i = 1; i <= n; i++) {if (A[i] > 0)add(S, i, 0, A[i]), tot += A[i];else if (A[i] < 0)add(i, T, 0, -A[i]);
}//上述add函数为
void add(int a, int b, int c, int d) {to[idx] = b, wei[idx] = d - c, l[idx] = c, nexte[idx] = head[a], head[a] = idx++;to[idx] = a, wei[idx] = 0, nexte[idx] = head[b], head[b] = idx++;
}

这时候问题就转化成了与https://blog.csdn.net/Tinberlake/article/details/119751664?spm=1001.2014.3001.5501上相同的有源求最大流问题,此时每个边在原图中的流量就是新图中计算的流量加上其下届流量fmin(u,v)+c′(u,v)fmin(u, v) + c'(u, v)fmin(u,v)+c′(u,v) 。

有源汇上下界最大流

此时的网络中有源点,每个结点只能接受从源点汇来的流量,无法同无源汇上下界可行流一样通过填补每个结点的流量进行计算。

此时如何求得网络的最大流?此时,先将题目中的源点与汇点定义为sss与ttt,另新建两虚拟结点SSS与TTT,建立一条ttt到sss可行流量为无穷的边,此时先将问题转化成了无源汇上下界可行流。

那么,为何从汇点到源点建立一条流量为正无穷的边?保证流量守恒

若要求最大流,则从sss到ttt的流量一定为正,0≤c(s,t)0 \le c(s, t)0≤c(s,t) ,若要保证新图与旧图流量守恒的一致,则需要在ttt到sss之间建立一条流量为无穷的边。

那么,对于新图中流量若小于从虚拟源点流出的最大流,则可证明没有一条可行流满足从sss到ttt,此时存在边不满足下届。

当新图中的流量不小于虚拟源点流出的最大流,此时截断从ttt到sss流量为无穷的边,并将此边的逆边流量记录为resresres。将源汇点更改为sss与ttt,那么,新图中sss到ttt的残留网络的最大流加上resresres即为有源汇上下界最大流的流量。

为何?新图中无源汇的可行流构建了一个可行流,这个可行流最大时,代表所有结点的流量均守恒,此时的残留网络,若去除ttt到sss之间流量为无穷的结点,则代表此时除去这两点外,其余所有点的流量均守恒。这两点作为源点与汇点,不必守恒,因此此时计算去边后残留网络的最大流,可以保证整个网络的流量是守恒的。又因为,新图中原本sss到ttt的不守恒流量的大小,就是被截断边的逆边的流量,因此sss到ttt的最大可行流就是resresres加新图中sss到ttt的残留网络的最大流。

代码

cin >> n >> m >> s >> t;
S = 0, T = n + 1;
memset(head, -1, sizeof head);
while(m--){int a, b, c, d;cin >> a >> b >> c >> d;add(a, b, d - c);A[a] -= c, A[b] += c;
}
int all = 0;
for(int i = 1; i <= n; i++){if(A[i] > 0) add(S, i, A[i]), all += A[i];else if(A[i] < 0) add(i, T, -A[i]);
}
add(t, s, INF);
if(dinic() < all) cout << "No Solution\n";
else{int ans = wei[idx - 1];S = s, T = t;wei[idx - 1] = wei[idx - 2] = 0;cout << ans + dinic() << '\n';
}//上述add函数为
void add(int a,int b, int c){to[idx] = b, wei[idx] = c, nexto[idx] = head[a], head[a] = idx++;to[idx] = a, wei[idx] = 0, nexto[idx] = head[b], head[b] = idx++;
}

有源汇上下界最小流

根据有源汇上下界最大流的相关计算,可知若要sss到ttt是最小流,则此时ttt到sss的可行流最大,因此只需按有源汇上下界最大流建图后,更改源汇点为ttt与sss即可。

代码

cin >> n >> m >> s >> t;
S = 0, T = n + 1;
memset(head, -1, sizeof head);
while(m--){int a, b, c, d;cin >> a >> b >> c >> d;add(a, b, d - c);A[a] -= c, A[b] += c;
}
int all = 0;
for(int i = 1; i <= n; i++){if(A[i] > 0) add(S, i, A[i]), all += A[i];else if(A[i] < 0) add(i, T, -A[i]);
}
add(t, s, INF);
if(dinic() < all) cout << "No Solution\n";
else{int ans = wei[idx - 1];S = t, T = s;wei[idx - 1] = wei[idx - 2] = 0;cout << ans - dinic() << '\n';
}

上下界网络流-无源汇可行流与有源汇最大流相关推荐

  1. 【有上下界网络流】【ZOJ】2314 Reactor Cooling

    [算法]有上下界网络流-无源汇(循环流) [题解]http://www.cnblogs.com/onioncyc/p/6496532.html //未提交 #include<cstdio> ...

  2. 有上下界网络流 ---- Zoj3229 Shoot the Bullet|东方文花帖|【模板】有源汇上下界最大流

    学习资料+题目链接 题目大意: 模板讲解 #include <bits/stdc++.h> #define mid ((l + r) >> 1) #define Lson rt ...

  3. HDU 4940 Destroy Transportation system(无源汇上下界网络流)

    Problem Description Tom is a commander, his task is destroying his enemy's transportation system. Le ...

  4. 有上下界网络流 ---- P4843 清理雪道(DAG图上最小路径重复边覆盖)【模板】有源汇上下界最小流

    题目链接 题目大意: 解题思路: 首先我们发现对于每条边至少要覆盖一次,最多覆盖无数次 那么就有点像上下界网络流了[1,INF][1,INF][1,INF]的限制关系 跑一边最小流就可以了!! #in ...

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

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

  6. 有上下界的网络流1-无源汇带上下界网络流SGU194

    有上下界的网络流1-无源汇带上下界网络流SGU194 今天开始啃网络流了.对于求解无源汇带上下界的网络流,我们可以这样建图: 建图模型:          以前写的最大流默认的下界为0,而这里的下界却 ...

  7. 有上下界网络流问题汇总

    无源汇有上下界可行流 法一(据说适合点少边多的图): 建图方法 首先建立附加源点ss和附加汇点tt 对于原图中的边x->y,若限制为[b,c],那么连边x->y,流量为c-b 对于原图中的 ...

  8. 学习上下界网络流小记

    前言 这个上下界网络流是一个以前我这个巨弱弱想都不敢想的一个东西. 然而,最近一次比赛居然考了这个东东. 于是整个机房掀起了破烂学上下界网络流的热. 那么我也来学学. 预备知识 要懂得很多很多的网络流 ...

  9. 模板 - 上下界网络流

    整理的算法模板合集: ACM模板 目录 无源汇上下界可行流 有源汇上下界最大流 有源汇上下界最小流 无源汇上下界可行流 /*首先建立一个源S和一个汇T,一般称为附加源和附加汇.对于图中的每条弧< ...

最新文章

  1. subList用法详解
  2. opencv、matplotlib、pillow和pytorch读取数据的通道顺序
  3. 为什么选择Netty作为基础通信组件?
  4. #1081 : 最短路径·一(Dijkstra)
  5. TypeError: Expected bytes错误解决方法
  6. .NET异常设计原则
  7. 带哨兵节点的链_HBA公链 | IPFS:区块链“不可能三角”的可能解
  8. 云服务器如何链接本地打印机_利用FileZilla搭建云服务器FTP服务端和本地客户端...
  9. 32岁转行还来得及吗?
  10. 高通混频器配置文件如何选择
  11. Java和python哪个好,学哪个有用。
  12. Word与Excel展示Oracle BI Publisher页签
  13. mysql 计算农历_公历转换农历算法
  14. 计算机上的aece代表什么意思,Myristicaceae是什么意思
  15. 让你心静的七十五条经典修心格言(转)
  16. 广告联盟源码java_Android启动页广告(腾讯广告联盟)解决方法及源码下载
  17. Python-pip镜像源配置及国内常用镜像源
  18. 11. WS · HTTPDNS · FTP · 邮件
  19. 使用Keras以inceptionV3作为主干网络进行迁移学习遇到的问题
  20. 2.利用docker+雨巷云打造私有网盘之安装nextcloud14.0.13

热门文章

  1. 探索Julia(part7)--数组与字典函数
  2. 走近分形与混沌(part15)--有钱的人会愈来愈有钱,不一定是在于他们的能力,而是因为财富会产生财富
  3. matlab图像去毛刺_信号去毛刺,去零漂
  4. python质数n以内_用Python寻找前n个质数
  5. 你聚类个数是靠拍的?
  6. Python报表自动化
  7. 如何在 SAP 电商云 Spartacus 代码里获取 Routes 路由信息
  8. 如何修改Cypress 测试代码中默认的超时时间(timeout)
  9. SAP Spartacus State
  10. Angular ActivatedRouteSnapshot