Skip to content
Snippets Groups Projects
Commit 39ab5757 authored by Bruno Freitas Tissei's avatar Bruno Freitas Tissei
Browse files

Add dinic's algorithm

parent b0a4a96b
No related branches found
No related tags found
No related merge requests found
/**
* Dinic's
*
* Complexity (Time): O(E*V^2)
* Complexity (Space): O(V + E)
*/
// Edge struct to be used in adjacency list similar to vector<ii> graph[MAX],
// but storing more information than ii
typedef struct edge {
int u;
int flow, cap;
// Id of the reverse edge on graph[u]
int rev;
edge(int u, int flow, int cap, int rev) :
u(u), flow(flow), cap(cap), rev(rev)
{}
} egde;
int depth[MAX];
int start[MAX];
vector<edge> graph[MAX];
// Adds edge between s and t with capacity c
void add_edge(int s, int t, int c) {
edge forward(t, 0, c, graph[t].sz);
edge backward(s, 0, 0, graph[s].sz);
graph[s].pb(forward);
graph[t].pb(backward);
}
// Calculates depth of each vertex from source, considering only
// edges with remaining capacity
bool bfs(int s, int t) {
queue<int> Q;
Q.push(s);
mset(depth, -1);
depth[s] = 0;
while (!Q.empty()) {
int v = Q.front(); Q.pop();
for (auto i : graph[v]) {
if (depth[i.u] == -1 && i.flow < i.cap) {
depth[i.u] = depth[v] + 1;
Q.push(i.u);
}
}
}
return depth[t] != -1;
}
// Finds bottleneck flow and add to the edges belonging to the paths found
int dfs(int s, int t, int flow) {
if (s == t)
return flow;
// Start iteration from where it last stopped to avoid repetitions
for ( ; start[s] < graph[s].sz; ++start[s]) {
edge &e = graph[s][start[s]];
// If the next vertex is further from the source (and closer to the sink)
// and the edge is not at full capacity, then explore it
if (depth[e.u] == depth[s] + 1 && e.flow < e.cap) {
int min_flow = dfs(e.u, t, min(flow, e.cap - e.flow));
if (min_flow > 0) {
e.flow += min_flow;
graph[e.u][e.rev].flow -= min_flow;
return min_flow;
}
}
}
return 0;
}
// Returns maximum flow between s and t
int dinic(int s, int t) {
int ans = 0;
// Run bfs to set depth array (depth of each vertex from source)
while (bfs(s, t)) {
mset(start, 0);
// Find every available path from the current depth information,
// set the flow of the edges and add the pushed flow to the answer
while (int flow = dfs(s, t, inf))
ans += flow;
}
return ans;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment