ISAP是对SAP进行优化后的算法,ISAP时间复杂度为O(V^2E),SAP的时间复杂度为O(VE^2)

SAP

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <iomanip>
  4. #include <queue>
  5. using namespace std;
  6. const int maxn = 100;
  7. const int INF = (1 << 30) - 1;
  8. int g[maxn][maxn];//残余网络
  9. int f[maxn][maxn];//实流网络
  10. int Prev[maxn];//保存前驱节点
  11. bool visited[maxn];
  12. int n, m;
  13. bool BFS(int s,int t)
  14. {
  15. int i;
  16. memset(Prev, -1, sizeof(Prev));
  17. memset(visited, false, sizeof(visited));//初始化
  18. queue<int> q;
  19. visited[s] = true;
  20. q.push(s);
  21. while (!q.empty())
  22. {
  23. int now = q.front();
  24. q.pop();
  25. for (i = 1; i <= n; i++)
  26. {
  27. if (!visited[i] && g[now][i]>0)//没被访问并且有边相连
  28. {
  29. visited[i] = true;
  30. Prev[i] = now;
  31. if (i == t)return true;//找到一条增广路劲
  32. q.push(i);
  33. }
  34. }
  35. }
  36. return false;
  37. }
  38. int EK(int s, int t)
  39. {
  40. int v, w, d, maxflow;
  41. maxflow = 0;
  42. while (BFS(s, t))//还有增广路径
  43. {
  44. v = t;
  45. d = INF;
  46. while (v != s)//向前找
  47. {
  48. w = Prev[v];
  49. if (d > g[w][v])
  50. {
  51. d = g[w][v];
  52. }
  53. v = w;
  54. }
  55. maxflow += d;
  56. v = t;
  57. while (v != s)
  58. {
  59. w = Prev[v];
  60. g[w][v] -= d;
  61. g[v][w] += d;
  62. if (f[v][w] > 0)
  63. {
  64. f[v][w] -= d;
  65. }
  66. else
  67. f[w][v] += d;
  68. v = w;
  69. }
  70. }
  71. return maxflow;
  72. }
  73. void Print()
  74. {
  75. cout << endl;
  76. for (int i = 1; i <= n; i++)
  77. {
  78. cout << setw(7) << "v" << i;
  79. }
  80. cout << endl;
  81. for (int i = 1; i <= n; i++)
  82. {
  83. cout<< "v" << i;
  84. for (int j = 1; j <= n; j++)
  85. {
  86. cout << setw(7) << f[i][j] << " ";
  87. }
  88. cout << endl;
  89. }
  90. }
  91. int main()
  92. {
  93. int u, v, w;
  94. memset(g, 0, sizeof(g));
  95. memset(f, 0, sizeof(f));
  96. cin >> n >> m;
  97. for (int i = 1; i <= m; i++)
  98. {
  99. cin >> u >> v >> w;
  100. g[u][v] += w;
  101. }
  102. cout << EK(1, n) << endl;
  103. Print();
  104. return 0;
  105. }

ISAP

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <queue>
  4. using namespace std;
  5. const int INF = 0x3fffffff;
  6. const int M = 10000;
  7. const int N = 100;
  8. int g[N], h[N], parent[N];//g[n]表示高度为h[n]的节点的个数h[n]节点高度数组
  9. int top;
  10. struct Vexter
  11. {
  12. int first;
  13. }V[N];
  14. struct Edge//边结构体
  15. {
  16. int v, next;
  17. int flow, cap;
  18. }E[N];
  19. void init()
  20. {
  21. memset(V, -1, sizeof(V));
  22. top = 0;
  23. }
  24. void add_Edge(int u, int v, int c)
  25. {
  26. E[top].cap = c;
  27. E[top].flow = 0;
  28. E[top].next = V[u].first;
  29. E[top].v = v;
  30. V[u].first = top++;
  31. }
  32. void add(int u, int v, int c)
  33. {
  34. add_Edge(u, v, c);
  35. add_Edge(v, u, 0);//增加一条反向边
  36. }
  37. void set_h(int t, int n)
  38. {
  39. queue<int> q;
  40. memset(g, 0, sizeof(g));
  41. memset(h, -1, sizeof(h));
  42. h[t] = 0;
  43. q.push(t);//汇点进队
  44. while (!q.empty())
  45. {
  46. int v = q.front();
  47. q.pop();
  48. ++g[h[v]];
  49. for (int i = V[v].first; ~i; i = E[i].next)
  50. {
  51. int u = E[i].v;
  52. if (h[u] == -1)
  53. {
  54. h[u] = h[v] + 1;
  55. q.push(u);
  56. }
  57. }
  58. }
  59. cout << "初始化高度" << endl;
  60. cout << "h[ ]=";
  61. for (int i = 1; i <= n; i++)
  62. {
  63. cout << " " << h[i];
  64. }
  65. cout << endl;
  66. }
  67. int Isap(int s, int t, int n)
  68. {
  69. set_h(t, n);//标高
  70. int ans = 0, u = s, d;
  71. while (h[s] < n)
  72. {
  73. int i = V[u].first;
  74. if (u == s)
  75. {
  76. d = INF;
  77. }
  78. for (; ~i; i = E[i].next)
  79. {
  80. int v = E[i].v;
  81. if (E[i].cap>E[i].flow&&h[u] == h[v] + 1)
  82. {
  83. u = v;
  84. parent[v] = i;
  85. d = min(d, E[i].cap - E[i].flow);
  86. if (u == t)//到达汇点
  87. {
  88. cout << endl;
  89. cout << "增广路径: " << t;
  90. while (u != s)//向前到源点
  91. {
  92. int j = parent[u];
  93. E[j].flow += d;//反向边增流
  94. E[j ^ 1].flow -= d;
  95. u = E[j ^ 1].v;
  96. cout << "--" << u;
  97. }
  98. cout << "增流: " << d << endl;
  99. ans += d;
  100. d = INF;
  101. }
  102. break;
  103. }
  104. }
  105. if (i == -1)//搜索所有边后不能进行
  106. {
  107. if (--g[h[u]] == 0)
  108. {
  109. break;
  110. }
  111. int hmin = n - 1;
  112. for (int j = V[u].first; ~j; j = E[j].next)
  113. {
  114. if (E[j].cap > E[j].flow)
  115. {
  116. hmin = min(hmin, h[E[j].v]);
  117. }
  118. }
  119. h[u] = hmin + 1;
  120. cout << "重贴标签后的高度:" << endl;
  121. cout << "h[ ]=";
  122. for (int i = 1; i <= n; i++)
  123. {
  124. cout << " " << h[i];
  125. }
  126. cout << endl;
  127. ++g[h[u]];
  128. if (u != s)//回退一步
  129. {
  130. u = E[parent[u] ^ 1].v;
  131. }
  132. }
  133. }
  134. return ans;
  135. }
  136. void PrintFlow(int n)
  137. {
  138. cout << "-----实流边-----" << endl;
  139. for (int i = 1; i <= n; i++)
  140. {
  141. for (int j = V[i].first; ~j; j = E[j].next)
  142. {
  143. if (E[j].flow > 0)
  144. {
  145. cout << "v" << i << "--" << "v" << E[j].v << " " << E[j].flow;
  146. cout << endl;
  147. }
  148. }
  149. }
  150. }
  151. int main()
  152. {
  153. int n, m, u, v, c;
  154. cin >> n >> m;
  155. init();
  156. for (int i = 1; i <= m; i++)
  157. {
  158. cin >> u >> v >> c;
  159. add(u, v, c);
  160. }
  161. cout << endl;
  162. cout << "网络的最大流: " << Isap(1, n, n) << endl;
  163. PrintFlow(n);
  164. return 0;
  165. }

SAP和ISAP(网路最大流的两个增广路算法)相关推荐

  1. 网络最大流中一般增广路算法(标号法)

    网络最大流主要有两大类求解方法:增广路算法和预流推进算法 一般增广路算法:主要分为初始流为零流和初始流为非零流的情况!后者在标号的时候注意一条边是正向连接还是反向连接:若是反向的连接,那么在调整的时候 ...

  2. 网络流—Edmonds-Karp 最短增广路算法(最大流)

    网络流----Edmonds-Karp 最短增广路算法 ■求最大流的过程,就是不断找到一条源到汇的路径,然后构建残余网络,再在残余网络上寻找新的路径,使总流量增加,然后形成新的残余网络,再寻找新路径- ...

  3. 网络流之 最短增广路算法模板(SAP)

    数据输入格式:首先输入顶点个数n和弧数m,然后输入每条弧的数据.规定源点为顶点0,汇点为顶点n-1.每条弧的数据格式为:u,v,w,分别表示这条弧的起点,终点,容量.顶点序号从0开始. 代码: 1 # ...

  4. 最短增广路Isap算法 网络流

    最短增广路 请先理解 bfs的求增广路的算法,再来学习Isap算法 最短增广路Isap算法 图片来源 <趣学算法>人民邮电出版社 陈小玉 /* 最短可增广路:重贴标签算法Isap 算法设计 ...

  5. 【网络流】解题报告:luogu P2740 [USACO4.2]草地排水Drainage Ditches(Edmonds-Karp增广路,最大流模板)

    题目链接:草地排水 若一条从源点到汇点的路径上各条边的剩余容量都大于0,则称这条路径为一条增广路. Edmonds-Karp增广路的策略就是不断用bfs寻找增广路,直至网络中不在存在增广路为止. 在每 ...

  6. 最大流增广路(KM算法) HDOJ 1853 Cyclic Tour

    题目传送门 1 /* 2 KM: 相比HDOJ_1533,多了重边的处理,还有完美匹配的判定方法 3 */ 4 #include <cstdio> 5 #include <cmath ...

  7. 网络流:最大流,最小割 基本概念及算法

    原文:http://www.cnblogs.com/Booble/archive/2011/03/04/1970453.html 参考:http://community.topcoder.com/tc ...

  8. 最大流的算法——Edmonds-Karp算法(最短路径增广算法)

    最大流的算法--Edmonds-Karp算法(最短路径增广算法) 这里介绍一个最简单的算法:Edmonds-Karp算法 即最短路径增广算法 简称EK算法 EK算法基于一个基本的方法:Ford-Ful ...

  9. 算法学习笔记:网络流#4——ISAP 求解最大流

    算法学习笔记:网络流#4--ISAP 求解最大流 1. 前言 2. 模板 2.1 详解 2.2 正确性证明 2.3 代码 3. 算法对比 3.1 一般数据下的对比 3.2 特殊数据下的对比 4. 总结 ...

最新文章

  1. 转: 浅析Fusion-IO和Intel SSD
  2. 《HTML5触摸界面设计与开发》——导读
  3. python 消息机制_Python并发编程之线程消息通信机制任务协调(四)
  4. 状态模式 设计模式_设计模式:状态
  5. 《零基础》MySQL 管理(三)
  6. 作者:陈钧,男,中国国防科技信息中心高级工程师、研究室主任。
  7. cmd查看开放的端口
  8. (转)华为面试题算什么,这个背会了外企随便进
  9. 从零基础入门Tensorflow2.0 ----三、10. 近似求导
  10. java开发利器 eclipse从入门到精通 pdf_Java从入门到精通(第4版)高清PDF下载
  11. Linux驱动开发-编写OLED显示屏驱动
  12. 【单片机仿真】(二)keil 安装教程
  13. vmware使用显卡
  14. NDoc 用户指南(转)
  15. 极米H5值得入手吗?极米H5实际体验如何?画面对比实测
  16. 董卫凤:不服输的华丽转身(三)
  17. 国外7个免费的网络主机服务
  18. Apache http Server与Tomcat整合 2
  19. 云服务器+ngrok搭建内网穿透服务(只有公网ip无域名)
  20. LCD显示器的模拟和数字接口

热门文章

  1. PMP证书获取指南来了
  2. 麻将打牌有三不打,记住了就不会亏!
  3. 机械图样解读——回转面
  4. 一篇让你彻底搞定HTTP方法与状态码
  5. 手把手教你编写 QQ 机器人
  6. python Django Session,CSRF,Model操作,Form验证,中间件,缓存,信号
  7. 如何批量删除把我删除(拉黑)的微信好友
  8. Planner 5D for Mac 4.8.2 2D/3D室内设计工具
  9. c语言 conio h,c语言中conio.h是什么?
  10. 腹直肌整体(06):仰卧直腿两头起