最大流三大算法——3,ISAP算法
最大流背景介绍:比如城市水管,从水站运水送你家,许多管道总共能同时送多少水到
最大流分三个算法,算法难度与优越性逐步提升:
1,EK(Edmonds−Karp)算法
2,dinic算法
3,ISAP算法
1,算法特点
我们已经明白了dinic的优越性了(只要不是毒瘤题就不会去卡他的),但是每次dfs跑完都要bfs重新建图,还是有点太繁琐了,我们能不能一劳永逸呢
ISAP(Improved Shortest Augumenting Path)做得到
ISAP大概就是bfs逆向建图,然后遍历每个点并标记其深度(这是核心思想,待会细说),之后从起点遍历到终点(每次深入必须满足点之间的深度差为1),如果一条增广路走完,且路上的某个点被增广过(后面无法再走了),那么这个点及其前面的点深度加一。
这样不断dfs,直到出现断层或者起点的深度大于n,跳出。
gap的作用大概是这样
2,还是他P3376 【模板】网络最大流
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int INF = 0x3f3f3f3f;
const int N = 250;
const int M = 6500;int n, m, s, t;
ll ans;
ll num;
ll head[M << 1];
ll now[M << 1];
ll gap[N];
ll dep[N];
struct node
{ll next, to, w;
} edge[M << 1];
void add(ll u, ll v, ll w)
{edge[++num].next = head[u];edge[num].to = v;edge[num].w = w;head[u] = num;edge[++num].next = head[v];edge[num].to = u;edge[num].w = 0;head[v] = num;}void bfs()
{memset(dep, -1, sizeof(dep));//我们从终点出发,对没有建立深度(dep为-1的点建立,终点深度为0)dep[t] = 0;gap[0]++;//gap记录每个深度有多少点,不要忘记终点这里gap[0]++queue<int>q;q.push(t);while (!q.empty()){int x = q.front();q.pop();for (int i = head[x]; i; i = edge[i].next){int v = edge[i].to;ll w=edge[i^1].w;//方向建图,需要确定的是正向边的值,而不是反向边,所以w是异或的if (dep[v] == -1&&w){dep[v] = dep[x] + 1;//深度加一,然后gap增加gap[dep[v]]++;q.push(v);}}}
}ll dfs(int x, ll sum)
{if (x == t){ans += sum;//ans为我们目标return sum;//到终点了,目前剩下的sum流就都可以算入}ll k, res = 0;for (int i = now[x]; i && sum; i = edge[i].next)//now当前弧优化{now[x] = i;//记得更新当前弧int v = edge[i].to;ll w = edge[i].w;if (dep[v] == dep[x] - 1 && w)//注意,深度是越靠近终点越小,所以是dep[v] == dep[x] - 1,是-1{k = dfs(v, min(w, sum));if (!k)continue;//k等于0,后面几步没必要浪费时间edge[i].w -= k;edge[i ^ 1].w += k;res += k;sum -= k;if (!sum)return res;//如果sum==0,说明这个点已经负荷了,不能再有流通过了,则不用提高深度,直接返回跳出}}gap[dep[x]]--;//当前深度点-1if (!gap[dep[x]])dep[s] = n + 1;//如果发现断层,直接剪枝,不再dfsdep[x]++;//x深度加一gap[dep[x]]++;//对应深度点+1return res;//gap操作后再返回(对于遍历完其路径后还有容量可以流的点
}
int main()
{cin >> n >> m >> s >> t;ll u, v, w;num = 1;//初始值num要赋值1for (int i = 1; i <= m; ++i){cin >> u >> v >> w;add(u, v, w);}bfs();//一遍bfs建立深度ans = 0;while (dep[s] < n&&dep[s]!=-1)//有可能图本来就不连通,这样就无法bfs从t建到s,这样就会在这里死循环,所以先判断你是连通再说{memcpy(now, head, sizeof(head));//每次重新dfs,都要重新初始now值与head相同(因为dinic每次都有bfs重新建立所以不用专门初始化)dfs(s, INF);}cout << ans << endl;return 0;
}
最大流三大算法——3,ISAP算法相关推荐
- 网络流最大流算法(ISAP算法及DINIC算法)
这些算法网络中解释都有,所有以下是根据题目应用,代码中有注释,方便理解,ISAP算法就是通过先bfs一遍建立逆序求层数,然后每次都进行维护求最短路来求增广路径,下次查找建立在上次查找的最小路径的源点进 ...
- 最大流ISAP算法模板
这两天学习了最大流,下面是ISAP算法模板: const int inf = 0x3fffffff; template <int N, int M> struct Isap {int to ...
- Drainage Ditches【究极最大流算法之ISAP】(Improved Shortest Augmeng Path)
题目链接(一道模板的最大流问题) 我们都知道,Dinic算法求最大流的时候,每次都是需要去重新跑一遍分层图,那么现在有没有什么不需要再这样一次又一次地跑一遍分层图的做法呢? 我们知道,其实每次改变的深 ...
- 网络流之最大流 EK/Dinic/Isap算法 学习笔记
EK 算法流程 不停地找增广路进行增广,知道找不到增广路为止. 每一次bfs只找一条增广路. 时间复杂度O(VE2)O(VE^2) 代码 // codevs 1993 #include<iost ...
- 最大流算法之ISAP
序: 在之前的博文中,我解释了关于最大流的EK与Dinic算法,以及它们的STL/非STL的实现(其实没什么区别).本次讲解的是ISAP算法.'I',指 improved,也就是说ISAP其实是SAP ...
- 网络流FF,EK,dinicm, isap算法板子//带注释
FF算法 #include <iostream> #include <cstdio> #include <stack> #include <sstream&g ...
- 【网络流】最大流问题(EK算法带模板,Dinic算法带模板及弧优化,ISAP算法带模板及弧优化)上下界网络流
本blog重点是代码 网络流的相关概念 流网络(flow network) 流(flow) 网络的流 残留网络(residual network) 增广路径(augmenting path) Edmo ...
- 算法高级(7)-限流(Rate limit)算法详解
一.前言 保障服务稳定的三大利器:熔断降级.服务限流和故障模拟.今天和大家谈谈限流算法的几种实现方式,本文所说的限流并非是Nginx层面的限流,而是业务代码中的逻辑限流. 那么为什么需要限流呢? 按照 ...
- 网络流-最大流问题 ISAP 算法
ISAP 是图论求最大流的算法之一,它很好的平衡了运行时间和程序复杂度之间的关系,因此非常常用. 约定 我们使用邻接表来表示图,表示方法可以见文章带权最短路 Dijkstra, SPFA, Bellm ...
最新文章
- poj 1469 COURSES
- 对面向对象设计原则的总结
- 火狐自动换行 有空格
- 关于企业信息化中审计流程“寻租”现象的探讨
- 算法提高课-图论-单源最短路的建图方式-AcWing 1127. 香甜的黄油:spfa最短路
- 使用混合多云每个人都应避免的3个陷阱(第1部分)
- 执行 Python 程序的三种方式及Python 的 IDE —— `PyCharm`
- 大家好 我是新来的
- 数据架构总体设计方案
- Eclipse 启动不了 Tomcat
- vue生产环境使用localhost请求端口号不是自己设置的?来试试这个
- android 连接电视,手机连接电视方法大全
- 全国银行开户行名称查询数据库,包括行号、电话、地址、
- 锐捷网络2019年秋招售前产品经理面试总结
- 联想家庭版 mysql_联想自带win7家庭版..
- 自动化测试的思考及其工具的设计
- java类与接口思维导图_详解java接口基础知识附思维导图
- NeurIPS 会议怎么读
- 《Linux系统管理与应用》课程知识点整理+书后习题全文解答(Linux知识点大纲)
- python中的海归制图(turtle)绘制文字