Skip to content
This repository was archived by the owner on Nov 29, 2020. It is now read-only.

Commit ee25801

Browse files
committed
FordFulkerson.cpp
1 parent f91dfef commit ee25801

File tree

3 files changed

+104
-2
lines changed

3 files changed

+104
-2
lines changed

FordFulkerson.cpp

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//
2+
// algorithm - some algorithms in "Introduction to Algorithms", third edition
3+
// Copyright (C) 2018 lxylxy123456
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as
7+
// published by the Free Software Foundation, either version 3 of the
8+
// License, or (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
//
18+
19+
#ifndef MAIN
20+
#define MAIN
21+
#define MAIN_FordFulkerson
22+
#endif
23+
24+
#ifndef FUNC_FordFulkerson
25+
#define FUNC_FordFulkerson
26+
27+
#include "utils.h"
28+
29+
#include "BFS.cpp"
30+
31+
template <typename GT, typename T, typename WT>
32+
void FordFulkerson(GT& G, umap<Edge<T>, WT, EdgeHash<size_t>>& c,
33+
T s, T t, umap<Edge<T>, WT, EdgeHash<size_t>>& f) {
34+
for (auto i = G.all_edges(); !i.end(); i++)
35+
f[*i] = 0;
36+
auto get_c = [&G, &c, &f](T u, T v) mutable -> WT {
37+
if (G.is_edge(u, v)) {
38+
Edge<T> e = Edge<T>(u, v, G.dir);
39+
return c[e] - f[e];
40+
} else if (G.is_edge(v, u))
41+
return f[Edge<T>(v, u, G.dir)];
42+
else
43+
return 0;
44+
};
45+
while (true) {
46+
GT Gf(G.dir);
47+
for (auto i = G.all_edges(); !i.end(); i++) {
48+
T u = i.s(), v = i.d();
49+
if (get_c(u, v))
50+
Gf.add_edge(u, v);
51+
if (get_c(v, u))
52+
Gf.add_edge(v, u);
53+
}
54+
umap<T, BFSInfo<T>> BFS_ans;
55+
BFS(Gf, s, BFS_ans);
56+
std::vector<size_t> p;
57+
PrintPath(s, t, BFS_ans, p);
58+
if (!p.size())
59+
break;
60+
WT cfp = get_c(p[0], p[1]);
61+
for (size_t i = 2; i < p.size(); i++)
62+
cfp = std::min(cfp, get_c(p[i - 1], p[i]));
63+
for (size_t i = 1; i < p.size(); i++) {
64+
if (G.is_edge(p[i - 1], p[i]))
65+
f[Edge<T>(p[i - 1], p[i], G.dir)] += cfp;
66+
else
67+
f[Edge<T>(p[i], p[i - 1], G.dir)] -= cfp;
68+
}
69+
}
70+
}
71+
#endif
72+
73+
#ifdef MAIN_FordFulkerson
74+
int main(int argc, char *argv[]) {
75+
const size_t v = get_argv(argc, argv, 1, 5);
76+
const size_t e = get_argv(argc, argv, 2, 10);
77+
const bool dir = true;
78+
const int weight_lower = get_argv<int>(argc, argv, 3, 0);
79+
const int weight_upper = get_argv<int>(argc, argv, 4, e);
80+
GraphAdjList<size_t> G(dir);
81+
random_graph(G, v, e);
82+
umap<Edge<size_t>, int, EdgeHash<size_t>> c;
83+
random_weight(G, c, weight_lower, weight_upper);
84+
umap<Edge<size_t>, int, EdgeHash<size_t>> f;
85+
FordFulkerson(G, c, 0ul, v - 1ul, f);
86+
auto f1 = [v](size_t vv) {
87+
if (vv == v - 1 || vv == 0)
88+
std::cout << " [style=bold]";
89+
return false;
90+
};
91+
auto f2 = [c, f](Edge<size_t> e) mutable {
92+
std::cout << " [label=\"" << f[e] << "/" << c[e] << "\"";
93+
if (f[e])
94+
std::cout << " style=bold";
95+
std::cout << "]";
96+
};
97+
graphviz(G, f1, f2);
98+
return 0;
99+
}
100+
#endif
101+

Johnson.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ int main(int argc, char *argv[]) {
7171
const size_t v = get_argv(argc, argv, 1, 5);
7272
const size_t e = get_argv(argc, argv, 2, 10);
7373
const bool dir = get_argv<int>(argc, argv, 3, 1);
74-
const int weight_lower = get_argv<int>(argc, argv, 3, (0-e) / 4);
75-
const int weight_upper = get_argv<int>(argc, argv, 4, e);
74+
const int weight_lower = get_argv<int>(argc, argv, 4, (0-e) / 4);
75+
const int weight_upper = get_argv<int>(argc, argv, 5, e);
7676
GraphAdjList<size_t> G(dir);
7777
random_graph(G, v, e);
7878
umap<Edge<size_t>, int, EdgeHash<size_t>> w;

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@
164164
| 25 | FloydWarshall.cpp | Floyd Warshall | 695 |
165165
| 25 | TransitiveClosure.cpp | Transitive Closure | 698 |
166166
| 25 | Johnson.cpp | Johnson | 704 |
167+
| 26 | FordFulkerson.cpp | Ford Fulkerson | 724 |
167168

168169
# Supplementary Files
169170
* `utils.h`: Utils

0 commit comments

Comments
 (0)