最大流学习笔记

打印 上一主题 下一主题

主题 865|帖子 865|积分 2595

由于本人太弱,可能讲解有误,请读者指出。
什么是网络流

网络流是通过构建从源点到汇点的有向图模型来解决图论问题。从理论上讲,网络流可以处理所有二分图问题。
二分图和网络流的难度都在于问题建模,一般不会特意去卡算法效率,所以只需要背一两个简单算法的模板就能应付大部分题目了。
最大流问题

什么是最大流

例题

P3376 【模板】网络最大流
解释例题

将一些物品从结点 \(s\) 运输到结点 \(t\),其中可以通过其他的结点中转,每条边都有一条运输物品上限,求最多有多少物品可以从结点 \(s\) 运输到结点 \(t\)。
概念

源点:即结点 \(s\),出发点。
汇点:即结点 \(t\),结束点。
容量:记 \(c(u,v)\),从结点 \(u\) 到结点 \(v\) 的边的运输物品数量上限,若结点 \(u\) 与结点 \(v\) 之间不存在边,\(c(u,v)=0\)。
流量:记 \(f(u,v)\),从结点 \(u\) 到结点 \(v\) 的边实际运输物品数量。
残量:每条边的容量与流量之差。
由于若将物品从结点 \(u\) 运输到结点 \(v\),再又将物品运回来是没有任何意义的,所以可以规定 \(f(u,v)=-f(v,u)\)。
如图:每个边上第一个数是流量,第二个数是容量

性质

通过这些概念,我们就可以从中挖掘出一些性质:

  • 容量限制:\(f(u,v)\le c(u,v)\)。
  • 斜对称性:\(f(u,v)=-f(v,u)\)。
  • 流量平衡:\(\sum\limits_{u\ne\{s,t\},(u,v)\in E}f(u,v)=0\)。
这是最大流的重要性质,同时也是它的条件。
增广路算法

增广路算法思想很简单:从零流开始不断的增加流量,每一次增加要保持三条性质就行了。
我们通过每一条边的残量建边,对对原有边建立反向边,得到一个残量网络,注意这里边的数量可能达到原图的两倍:

这样,我们只需要基于这样的事实:残量网络中的任何一条 \(s\) 到 \(t\) 的有向道路都对应着一条原图中的增广路。只需要求出该道路中的所有残量最小值 \(d\),把所对应的所有边上的流量增加 \(d\) 即可,这个过程就叫增广。如图,红色的就是一条增广路。

不难验证在增广之后它还是满足三条性质的。
如果当图中不存在增广路时,就说明当前流就是最大流了。
这就是增广路定理。
实现——Edmonds-Karp 算法

对于查找路径,我们可以选用 DFS 或 BFS,但是如果用 DFS 则一不小心就会超时,所以应该选用 BFS来实现,时间复杂度 \(O(nm^2)\)。
Code
  1. int Bfs() {
  2.     memset(pre, -1, sizeof(pre));
  3.     for(int i = 1 ; i <= n ; ++ i) flow[i] = INF;
  4.     queue <int> q;
  5.     pre[S] = 0, q.push(S);
  6.     while(!q.empty()) {
  7.         int op = q.front(); q.pop();
  8.         for(int i = 1 ; i <= n ; ++ i) {
  9.             if(i==S||pre[i]!=-1||c[op][i]==0) continue;
  10.             pre[i] = op; //找到未遍历过的点
  11.             flow[i] = min(flow[op], c[op][i]); // 更新路径上的最小值
  12.             q.push(i);
  13.         }
  14.     }
  15.     if(flow[T]==INF)return -1;
  16.     return flow[T];
  17. }
  18. int Solve() {
  19.     int ans = 0;
  20.     while(true) {
  21.         int k = Bfs();
  22.         if(k==-1) break;
  23.         ans += k;
  24.         int nw = T;
  25.         while(nw!=S) {//更新残余网络
  26.             c[pre[nw]][nw] -= k;
  27.             c[nw][pre[nw]] += k;
  28.             nw = pre[nw];
  29.         }
  30.     }
  31.     return ans;
  32. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

半亩花草

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表