From 22edf84110d24bdb6478305a0c5906e1c7c8dec8 Mon Sep 17 00:00:00 2001 From: Bruno Freitas Tissei <bft15@inf.ufpr.br> Date: Fri, 22 Feb 2019 20:32:41 -0300 Subject: [PATCH] Add ford-fulkerson Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br> --- algorithms/graph/articulations_bridges.cpp | 4 +- algorithms/graph/bfs.cpp | 4 +- algorithms/graph/bipartite_match.cpp | 6 +-- algorithms/graph/dfs.cpp | 4 +- algorithms/graph/dijkstra.cpp | 4 +- algorithms/graph/floyd_warshall.cpp | 4 +- algorithms/graph/ford_fulkerson.cpp | 59 ++++++++++++++++++++++ algorithms/graph/kosaraju.cpp | 4 +- algorithms/graph/kruskal.cpp | 4 +- algorithms/graph/lca.cpp | 6 +-- algorithms/graph/prim.cpp | 4 +- algorithms/graph/tarjan.cpp | 4 +- algorithms/graph/topological_sort.cpp | 4 +- algorithms/structure/lazy_segment_tree.cpp | 2 +- algorithms/structure/segment_tree.cpp | 38 +++++++++----- notebook/gen_latex.py | 19 ++++--- testing.py | 53 +++++++++++++++++++ 17 files changed, 172 insertions(+), 51 deletions(-) create mode 100644 algorithms/graph/ford_fulkerson.cpp create mode 100644 testing.py diff --git a/algorithms/graph/articulations_bridges.cpp b/algorithms/graph/articulations_bridges.cpp index 7ddb90e..73c9b6e 100644 --- a/algorithms/graph/articulations_bridges.cpp +++ b/algorithms/graph/articulations_bridges.cpp @@ -1,8 +1,8 @@ /** * Tarjan - Articulations and Bridges * - * Complexity (Time): O(n + m) - * Complexity (Space): O(n + m) + * Complexity (Time): O(V + E) + * Complexity (Space): O(V + E) */ vector<int> graph[MAX]; diff --git a/algorithms/graph/bfs.cpp b/algorithms/graph/bfs.cpp index 6431f2b..2317e9a 100644 --- a/algorithms/graph/bfs.cpp +++ b/algorithms/graph/bfs.cpp @@ -1,8 +1,8 @@ /** * Breadth First Search (BFS) * - * Complexity (Time): O(n + m) - * Complexity (Space): O(n + m) + * Complexity (Time): O(V + E) + * Complexity (Space): O(V + E) */ bool cont[MAX]; diff --git a/algorithms/graph/bipartite_match.cpp b/algorithms/graph/bipartite_match.cpp index dde0774..92215e4 100644 --- a/algorithms/graph/bipartite_match.cpp +++ b/algorithms/graph/bipartite_match.cpp @@ -1,8 +1,8 @@ /** - * Bipartite Matching (simplified Ford-Fulkerson) + * Bipartite Matching * - * Complexity (Time): O(n + m) - * Complexity (Space): O(n + m) + * Complexity (Time): O(V + E) + * Complexity (Space): O(V + E) */ vector<int> graph[MAX]; diff --git a/algorithms/graph/dfs.cpp b/algorithms/graph/dfs.cpp index 6408d40..1dd2da5 100644 --- a/algorithms/graph/dfs.cpp +++ b/algorithms/graph/dfs.cpp @@ -1,8 +1,8 @@ /** * Depth First Search (DFS) * - * Complexity (Time): O(n + m) - * Complexity (Space): O(n + m) + * Complexity (Time): O(V + E) + * Complexity (Space): O(V + E) */ bool cont[MAX]; diff --git a/algorithms/graph/dijkstra.cpp b/algorithms/graph/dijkstra.cpp index afb03e5..3328a27 100644 --- a/algorithms/graph/dijkstra.cpp +++ b/algorithms/graph/dijkstra.cpp @@ -1,8 +1,8 @@ /** * Dijkstra * - * Complexity (Time): O(m + n log n) - * Complexity (Space): O(n + m) + * Complexity (Time): O(E + V log V) + * Complexity (Space): O(V + E) */ int dist[MAX]; diff --git a/algorithms/graph/floyd_warshall.cpp b/algorithms/graph/floyd_warshall.cpp index f913d87..8774a58 100644 --- a/algorithms/graph/floyd_warshall.cpp +++ b/algorithms/graph/floyd_warshall.cpp @@ -1,8 +1,8 @@ /** * Floyd Warshall Algorithm * - * Complexity (Time): O(n^3) - * Complexity (Space): O(n^2) + * Complexity (Time): O(V^3) + * Complexity (Space): O(V^2) */ int dist[MAX][MAX]; diff --git a/algorithms/graph/ford_fulkerson.cpp b/algorithms/graph/ford_fulkerson.cpp new file mode 100644 index 0000000..87da194 --- /dev/null +++ b/algorithms/graph/ford_fulkerson.cpp @@ -0,0 +1,59 @@ +/** + * Ford-Fulkerson + * + * Complexity (time): O(Ef) + * Complexity (space): O(V + E) + */ + +int N; +int par[MAX]; +int graph[MAX][MAX], rg[MAX][MAX]; + +bool cont[MAX]; + +// Finds if there's a path between s and t using non-full +// residual edges +bool path(int s, int t) { + cont[s] = true; + if (s == t) + return true; + + for (int i = 0; i < N; ++i) + if (!cont[i] and rg[s][i]) { + par[i] = s; + if (path(i, t)) + return true; + } + + return false; +} + + +// Returns maximum flow between s (source) and t (sink) +int ford_fulkerson(int s, int t) { + int ans = 0; + par[s] = -1; + + mset(cont, 0); + memcpy(rg, graph, sizeof(graph)); + + // Repeat while there's a valid path between s and t + while (path(s, t)) { + int flow = inf; + + // Get the minimum capacity among all edges of the chosen path + for (int i = t; par[i] != -1; i = par[i]) + flow = min(f, rg[par[i]][i]); + + // Update residual graph + for (int i = t; par[i] != -1; i = par[i]) { + rg[par[i]][i] -= flow; + rg[i][par[i]] += flow; + } + + ans += flow; + mset(cont, 0); + } + + return ans; +} diff --git a/algorithms/graph/kosaraju.cpp b/algorithms/graph/kosaraju.cpp index b675ca5..486883b 100644 --- a/algorithms/graph/kosaraju.cpp +++ b/algorithms/graph/kosaraju.cpp @@ -1,8 +1,8 @@ /** * Kosaraju * - * Complexity (Time): O(n + m) - * Complexity (Space): O(n + m) + * Complexity (Time): O(V + E) + * Complexity (Space): O(V + E) */ stack<int> S; diff --git a/algorithms/graph/kruskal.cpp b/algorithms/graph/kruskal.cpp index 7cc272a..383808e 100644 --- a/algorithms/graph/kruskal.cpp +++ b/algorithms/graph/kruskal.cpp @@ -1,8 +1,8 @@ /** * Kruskal * - * Complexity (Time): O (m log n) - * Complexity (Space): O(m) + * Complexity (Time): O (E log V) + * Complexity (Space): O(E) * * #include <structure/disjoint_set> * diff --git a/algorithms/graph/lca.cpp b/algorithms/graph/lca.cpp index 8919ff7..32a2fce 100644 --- a/algorithms/graph/lca.cpp +++ b/algorithms/graph/lca.cpp @@ -2,9 +2,9 @@ * Lowest Common Ancestor - LCA * * Complexity (Time): - * - preprocess: O(n log n) - * - query: O(log n) - * Complexity (Space): O(n + m + n log n) + * - preprocess: O(V log V) + * - query: O(log V) + * Complexity (Space): O(V + E + V log V) * * OBS: * = return sum path to LCA * ** = return max value on path to LCA diff --git a/algorithms/graph/prim.cpp b/algorithms/graph/prim.cpp index 1229061..2270fa3 100644 --- a/algorithms/graph/prim.cpp +++ b/algorithms/graph/prim.cpp @@ -1,8 +1,8 @@ /** * Prim * - * Complexity (Time): O(m log m) - * Complexity (Space): O(n + m) + * Complexity (Time): O(E log E) + * Complexity (Space): O(V + E) */ bool cont[MAX]; diff --git a/algorithms/graph/tarjan.cpp b/algorithms/graph/tarjan.cpp index bfcccdc..ede8a49 100644 --- a/algorithms/graph/tarjan.cpp +++ b/algorithms/graph/tarjan.cpp @@ -1,8 +1,8 @@ /** * Tarjan - Strongly Connected Components * - * Complexity (Time): O(n + m) - * Complexity (Space): O(n + m) + * Complexity (Time): O(V + E) + * Complexity (Space): O(V + E) */ vector<int> graph[MAX]; diff --git a/algorithms/graph/topological_sort.cpp b/algorithms/graph/topological_sort.cpp index b4a7169..024828d 100644 --- a/algorithms/graph/topological_sort.cpp +++ b/algorithms/graph/topological_sort.cpp @@ -1,8 +1,8 @@ /** * Topological Sort * - * Complexity (Time): O(n + m) - * Complexity (Space): O(n + m) + * Complexity (Time): O(V + E) + * Complexity (Space): O(V + E) */ stack<int> S; diff --git a/algorithms/structure/lazy_segment_tree.cpp b/algorithms/structure/lazy_segment_tree.cpp index e53f12e..ea5c8a7 100644 --- a/algorithms/structure/lazy_segment_tree.cpp +++ b/algorithms/structure/lazy_segment_tree.cpp @@ -12,7 +12,7 @@ int N; int v[MAX]; int tree[4 * MAX], lazy[4 * MAX]; -#define left(x) ((x << 1)) +#define left(x) (x << 1) #define right(x) ((x << 1) + 1) // Builds tree with elements from v (0-indexed) diff --git a/algorithms/structure/segment_tree.cpp b/algorithms/structure/segment_tree.cpp index 05d22eb..a579079 100644 --- a/algorithms/structure/segment_tree.cpp +++ b/algorithms/structure/segment_tree.cpp @@ -8,44 +8,54 @@ * Complexity (Space): O(n) */ -int N, tree[4 * MAX], v[MAX]; +int N; +int v[MAX]; +int tree[4 * MAX]; + +#define left(x) (x << 1) +#define right(x) ((x << 1) + 1) // Build tree with elements from v -void build_tree(int node = 1, int a = 0, int b = N) { - if (a > b) return; +void build(int node = 1, int a = 0, int b = N - 1) { + if (a > b) + return; if (a == b) { tree[node] = v[a]; return; } - build_tree(node * 2, a, (a + b) / 2); - build_tree(node * 2 + 1, 1 + (a + b) / 2, b); + build_tree(left(node), a, (a + b) / 2); + build_tree(right(node), 1 + (a + b) / 2, b); tree[node] = tree[node * 2] + tree[node * 2 + 1]; } // Update position idx with value val -void update_tree(int idx, int val, int node = 1, int a = 0, int b = N) { - if (a > b || a > idx || b < idx) return; +void update(int idx, int val, int node = 1, int a = 0, int b = N - 1) { + if (a > b or a > idx or b < idx) + return; if (a == b) { tree[node] = val; return; } - update_tree(idx, val, node * 2, a, (a + b) / 2); - update_tree(idx, val, node * 2 + 1, 1 + (a + b) / 2, b); + update_tree(idx, val, left(node), a, (a + b) / 2); + update_tree(idx, val, right(node), 1 + (a + b) / 2, b); tree[node] = tree[node * 2] + tree[node * 2 + 1]; } // Return sum of [i,j] -int query_tree(int i, int j, int node = 1, int a = 0, int b = N) { - if (a > b || a > j || b < i) return 0; +int query(int i, int j, int node = 1, int a = 0, int b = N - 1) { + if (a > b or a > j or b < i) + return 0; - if (a >= i && b <= j) return tree[node]; + if (i <= a and b <= j) + return tree[node]; - return query_tree(i, j, node * 2, a, (a + b) / 2) + \ - query_tree(i, j, node * 2 + 1, 1 + (a + b) / 2, b); + int q1 = query_tree(i, j, left(node), a, (a + b) / 2); + int q2 = query_tree(i, j, right(node), 1 + (a + b) / 2, b); + return q1 + q2; } diff --git a/notebook/gen_latex.py b/notebook/gen_latex.py index 03ffba5..ef9134f 100644 --- a/notebook/gen_latex.py +++ b/notebook/gen_latex.py @@ -8,8 +8,8 @@ from pathlib import Path dirs = [ 'algorithms', 'misc', -# 'contests', -# 'problems' + 'contests', + 'problems' ] parser = argparse.ArgumentParser() @@ -67,22 +67,21 @@ for di in dirs: if '*/' in line: in_comment = False - in_ctime = False + if len(sections) > 2: + output.write('\\subsubsection{' + title + '}\n') + + in_complexity = 0 ctime, cspace = [], [] for line in comment: if 'Complexity (time)' in line: - in_ctime = True + in_complexity = 1 if 'Complexity (space)' in line: - in_ctime = False + in_complexity = 2 - if in_ctime: + if in_complexity: ctime.append(line) - - if len(sections) > 2: - output.write('\\subsubsection{' + title + '}\n') - # Remove first \n after header comment code = code[1:] diff --git a/testing.py b/testing.py new file mode 100644 index 0000000..74cd716 --- /dev/null +++ b/testing.py @@ -0,0 +1,53 @@ +from pathlib import Path + +dirs = [ + 'algorithms', + 'misc', + 'contests', + 'problems' +] + +def get_file_tree(): + tree = {} + for di in dirs: + path_list = Path(di).glob('**/*.cpp') + + for path in path_list: + branch = str(path).split('/') + + curr = tree + for i in branch[:-2]: + if not i in curr: + curr[i] = {} + curr = curr[i] + + if not branch[-2] in curr: + curr[branch[-2]] = [] + curr[branch[-2]].append(str(path)) + + return tree + + +def gen_code_latex(arr, depth): + for i in arr: + print('\\' + depth + '{' + i + '}') + +def gen_latex(tree): + stack = [ (tree, 0) ] + depth = ['chapter', 'section', 'subsection'] + + while len(stack) != 0: + x, h = stack.pop() + if type(x) == list: + for i in x: + gen_code_latex(x, depth[h]) + + #print('\\' + depth[h] + '{' + i + '}') + for i in x: + stack.append((x[i], h + 1)) + + + +tree = get_file_tree() +#print(tree) +gen_latex(tree) -- GitLab