博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
最大流算法
阅读量:5243 次
发布时间:2019-06-14

本文共 3445 字,大约阅读时间需要 11 分钟。

  链接

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 using namespace std; 14 15 int maxData = 0x3fffffff; 16 17 int augment(int des, vector
pre, vector
> path) { 18 if (pre[des] == -1) //残留图中不再存在增广路径 19 return -1; 20 else { 21 int res = maxData; 22 int cur_des = des; 23 int cur_pri = pre[des]; 24 while (cur_pri != -1) { 25 res = min(res, path[cur_pri][cur_des]); 26 cur_des = cur_pri; 27 if (pre[cur_pri] == -1) 28 break; 29 cur_pri = pre[cur_pri]; 30 } 31 return res; 32 } 33 } 34 int SPFA(int s, int des, vector
&pre, vector
> path) { 35 int n = path.size(); 36 queue
myqueue; 37 int i; 38 vector
d(n, -1); 39 for (i = 0; i < n; ++i) { //初始化前驱 40 pre[i] = -1; 41 } 42 for (i = 0; i < n; ++i) { 43 d[i] = maxData; //将除源点以外的其余点的距离设置为无穷大 44 } 45 vector
final(n, false); //记录顶点是否在队列中,SPFA算法可以入队列多次 46 vector
cnt(n, 0); //记录顶点入队列次数 47 d[s] = 0; //源点的距离为0 48 final[s] = true; 49 cnt[s]++; //源点的入队列次数增加 50 myqueue.push(s); 51 int topint; 52 while (!myqueue.empty()) { 53 topint = myqueue.front(); 54 myqueue.pop(); 55 final[topint] = false; 56 for (i = 0; i < n; ++i) { 57 if (d[topint] < maxData && d[i] > d[topint] + path[topint][i] 58 && path[topint][i] > 0) { 59 d[i] = d[topint] + path[topint][i]; 60 pre[i] = topint; 61 if (!final[i]) { //判断是否在当前的队列中 62 final[i] = true; 63 cnt[i]++; 64 if (cnt[i] >= n) //当一个点入队的次数>=n时就证明出现了负环。 65 return true; //剩余网络中不会出现负数,且单位费用相当于1,这种算法更适合最小费用最大流 66 myqueue.push(i); 67 } 68 } 69 } 70 } 71 return augment(des, pre, path); //返回增广路径的值 72 } 73 74 int BFS(int src, int des, vector
& pre, vector
> capacity) { //EK算法使用BFS寻找增广路径 75 queue
myqueue; 76 int i; 77 int n = capacity.size(); //如果没错的话应该和pre的size一样 78 vector
flow(n, 0); //标记从源点到当前节点实际还剩多少流量可用 79 while (!myqueue.empty()) //队列清空 80 myqueue.pop(); 81 for (i = 0; i < n; ++i) { //初始化前驱 82 pre[i] = -1; 83 } 84 flow[src] = maxData; //初始化源点的流量为无穷大 85 myqueue.push(src); 86 while (!myqueue.empty()) { 87 int index = myqueue.front(); 88 myqueue.pop(); 89 if (index == des) //找到了增广路径 90 break; 91 for (i = 0; i < n; ++i) { //遍历所有的结点 92 if (i != src && capacity[index][i] > 0 && pre[i] == -1) { 93 pre[i] = index; //记录前驱 94 flow[i] = min(capacity[index][i], flow[index]); //关键:迭代的找到增量 95 myqueue.push(i); 96 } 97 } 98 } 99 if (pre[des] == -1) //残留图中不再存在增广路径100 return -1;101 else102 return flow[des];103 }104 int maxFlow(int src, int des, vector
> capacity) {105 106 int increasement = 0; //增广路径的值107 int sumflow = 0; //最大流108 int n = capacity.size();109 vector
pre(n, -1); //标记在这条路径上当前节点的前驱,同时标记该节点是否在队列中110 while ((increasement = BFS(src, des, pre, capacity)) != -1) {111 int k = des; //利用前驱寻找路径112 while (k != src) {113 int last = pre[k];114 capacity[last][k] -= increasement; //改变正向边的容量115 capacity[k][last] += increasement; //改变反向边的容量116 k = last;117 }118 sumflow += increasement;119 }120 return sumflow;121 }122 123 int main() {124 vector
> path(4, vector
(4, 0)); //记录残留网络的容量125 vector
d(4, maxData);126 for (int i = 0; i < 4; i++)127 path[i][i] = maxData;128 path[0][1] = path[1][0] = path[2][3] = 1;129 path[1][2] = 5;130 path[0][2] = 3;131 path[1][3] = 2;132 path[2][1] = 2;133 path[0][3] = 3;134 int sum = maxFlow(0, 3, path);135 cout << sum;136 return 0;137 }

 

 

 

转载于:https://www.cnblogs.com/kakamilan/archive/2012/08/11/2634072.html

你可能感兴趣的文章
重置GNOME-TERMINAL
查看>>
redis哨兵集群、docker入门
查看>>
hihoCoder 1233 : Boxes(盒子)
查看>>
oracle中anyData数据类型的使用实例
查看>>
C++对vector里面的元素排序及取任意重叠区间
查看>>
软件测试——性能测试总结
查看>>
12.4站立会议
查看>>
Java Concurrentmodificationexception异常原因和解决方法
查看>>
客户端访问浏览器的流程
查看>>
codeforces水题100道 第二十二题 Codeforces Beta Round #89 (Div. 2) A. String Task (strings)
查看>>
c++||template
查看>>
[BZOJ 5323][Jxoi2018]游戏
查看>>
编程面试的10大算法概念汇总
查看>>
Vue
查看>>
python-三级菜单和购物车程序
查看>>
条件断点 符号断点
查看>>
水平垂直居中
查看>>
MySQL简介
查看>>
设计模式之桥接模式(Bridge)
查看>>
jquery的$(document).ready()和onload的加载顺序
查看>>