Skip to content

Commit 3eabca7

Browse files
Merge pull request #271 from cruiz24/cruiz24-patch-1
Add Dinic's Algorithm
2 parents b4d687d + f2adb58 commit 3eabca7

3 files changed

Lines changed: 253 additions & 0 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Graph Algorithms
2+
3+
This directory contains implementations of various graph algorithms.
4+
5+
## Dinic's Algorithm for Maximum Flow
6+
7+
Dinic's algorithm is an efficient algorithm for computing the maximum flow in a flow network, improving on the Ford-Fulkerson algorithm. It runs in O(V²E) time and is much faster in practice for many problems.
8+
9+
### Key Concepts
10+
11+
1. **Flow Network**: A directed graph where each edge has a capacity and a flow, with source and sink vertices.
12+
2. **Level Graph**: A graph where vertices are assigned levels according to their shortest distance from the source.
13+
3. **Blocking Flow**: A flow where every path from source to sink has at least one saturated edge.
14+
15+
### Algorithm Steps
16+
17+
1. Create a level graph using BFS
18+
2. Find blocking flows using DFS
19+
3. Repeat until no more augmenting paths can be found
20+
21+
### Applications
22+
23+
- Network Flow Problems
24+
- Bipartite Matching
25+
- Image Segmentation
26+
- Circulation Problems
27+
- Scheduling Problems
28+
29+
### Usage Example
30+
31+
```cpp
32+
// Create a flow network with 6 vertices
33+
DinicMaxFlow network(6);
34+
35+
// Add edges (from, to, capacity)
36+
network.addEdge(0, 1, 16);
37+
network.addEdge(0, 2, 13);
38+
// ... more edges ...
39+
40+
// Calculate maximum flow from source (0) to sink (5)
41+
int maxFlow = network.maxFlow(0, 5);
42+
```
43+
44+
### References
45+
46+
- Dinic, E. A. (1970). "Algorithm for solution of a problem of maximum flow in networks with power estimation"
47+
- Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. (2009). "Introduction to Algorithms" (3rd ed.)
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/*
2+
* Dinic's Algorithm for Maximum Flow
3+
*
4+
* This algorithm finds the maximum flow in a flow network using concepts of
5+
* level graphs and blocking flows. It's one of the most efficient algorithms
6+
* for solving the maximum flow problem with time complexity O(V^2 * E).
7+
*
8+
* The key steps of Dinic's Algorithm are:
9+
* 1. Create a level graph using BFS
10+
* 2. Find blocking flows using DFS
11+
* 3. Repeat until no more augmenting paths can be found
12+
*
13+
* Author: Abhi
14+
* Date: October 2, 2025
15+
*/
16+
17+
#include <iostream>
18+
#include <vector>
19+
#include <queue>
20+
#include <limits>
21+
#include <algorithm>
22+
23+
using namespace std;
24+
25+
class DinicMaxFlow {
26+
private:
27+
struct Edge {
28+
int to; // Target vertex
29+
int flow; // Current flow
30+
int capacity; // Capacity
31+
int rev; // Index of the reverse edge in the adjacency list
32+
33+
Edge(int t, int c, int r) : to(t), flow(0), capacity(c), rev(r) {}
34+
};
35+
36+
vector<vector<Edge>> graph; // Adjacency list representation of the graph
37+
vector<int> level; // Level of each vertex in the level graph
38+
vector<int> next; // Next edge to be explored in DFS
39+
int vertices; // Number of vertices
40+
const int INF = numeric_limits<int>::max();
41+
42+
public:
43+
// Constructor
44+
DinicMaxFlow(int n) : vertices(n) {
45+
graph.resize(n);
46+
level.resize(n);
47+
next.resize(n);
48+
}
49+
50+
// Add an edge from u to v with capacity c
51+
void addEdge(int u, int v, int c) {
52+
// Add forward edge
53+
graph[u].emplace_back(v, c, graph[v].size());
54+
// Add reverse edge with 0 capacity (for the residual graph)
55+
graph[v].emplace_back(u, 0, graph[u].size() - 1);
56+
}
57+
58+
// Build the level graph using BFS
59+
bool buildLevelGraph(int source, int sink) {
60+
fill(level.begin(), level.end(), -1);
61+
level[source] = 0;
62+
63+
queue<int> q;
64+
q.push(source);
65+
66+
while (!q.empty()) {
67+
int u = q.front();
68+
q.pop();
69+
70+
for (const Edge& edge : graph[u]) {
71+
// If level is not assigned and there is capacity remaining
72+
if (level[edge.to] == -1 && edge.flow < edge.capacity) {
73+
level[edge.to] = level[u] + 1;
74+
q.push(edge.to);
75+
}
76+
}
77+
}
78+
79+
// Return true if sink is reachable in the level graph
80+
return level[sink] != -1;
81+
}
82+
83+
// Find augmenting paths and augment flow using DFS
84+
int sendFlow(int u, int sink, int flow) {
85+
if (u == sink)
86+
return flow;
87+
88+
// Try all remaining edges in the current level
89+
for (; next[u] < graph[u].size(); ++next[u]) {
90+
Edge& edge = graph[u][next[u]];
91+
92+
// If the edge leads to the next level and has remaining capacity
93+
if (level[edge.to] == level[u] + 1 && edge.flow < edge.capacity) {
94+
int curr_flow = min(flow, edge.capacity - edge.flow);
95+
int temp_flow = sendFlow(edge.to, sink, curr_flow);
96+
97+
// If flow was augmented
98+
if (temp_flow > 0) {
99+
// Update flow for the current edge and its reverse edge
100+
edge.flow += temp_flow;
101+
graph[edge.to][edge.rev].flow -= temp_flow;
102+
return temp_flow;
103+
}
104+
}
105+
}
106+
107+
return 0; // No augmenting path found
108+
}
109+
110+
// Calculate the maximum flow from source to sink
111+
int maxFlow(int source, int sink) {
112+
if (source == sink)
113+
return 0;
114+
115+
int total_flow = 0;
116+
117+
// Continue until there are no more augmenting paths
118+
while (buildLevelGraph(source, sink)) {
119+
// Reset the next[] array for the new level graph
120+
fill(next.begin(), next.end(), 0);
121+
122+
// Augment flow while possible
123+
int flow;
124+
while ((flow = sendFlow(source, sink, INF)) > 0) {
125+
total_flow += flow;
126+
}
127+
}
128+
129+
return total_flow;
130+
}
131+
132+
// Print the current flow network
133+
void printFlowNetwork() {
134+
cout << "Flow Network:" << endl;
135+
for (int u = 0; u < vertices; ++u) {
136+
for (const Edge& edge : graph[u]) {
137+
if (edge.capacity > 0) { // Only print forward edges
138+
cout << u << " -> " << edge.to << " : "
139+
<< edge.flow << "/" << edge.capacity << endl;
140+
}
141+
}
142+
}
143+
}
144+
};
145+
146+
// Example usage
147+
int main() {
148+
// Example 1: Simple network with 6 vertices
149+
cout << "Example 1:" << endl;
150+
DinicMaxFlow network1(6);
151+
152+
// Add edges (from, to, capacity)
153+
network1.addEdge(0, 1, 16);
154+
network1.addEdge(0, 2, 13);
155+
network1.addEdge(1, 2, 10);
156+
network1.addEdge(1, 3, 12);
157+
network1.addEdge(2, 1, 4);
158+
network1.addEdge(2, 4, 14);
159+
network1.addEdge(3, 2, 9);
160+
network1.addEdge(3, 5, 20);
161+
network1.addEdge(4, 3, 7);
162+
network1.addEdge(4, 5, 4);
163+
164+
int source1 = 0;
165+
int sink1 = 5;
166+
cout << "Maximum flow: " << network1.maxFlow(source1, sink1) << endl;
167+
network1.printFlowNetwork();
168+
cout << endl;
169+
170+
// Example 2: Bipartite matching problem
171+
cout << "Example 2 (Bipartite Matching):" << endl;
172+
// 0 is source, 7 is sink, 1-3 are left set, 4-6 are right set
173+
DinicMaxFlow network2(8);
174+
175+
// Add edges from source to left set
176+
network2.addEdge(0, 1, 1);
177+
network2.addEdge(0, 2, 1);
178+
network2.addEdge(0, 3, 1);
179+
180+
// Add edges from left set to right set (representing possible matches)
181+
network2.addEdge(1, 4, 1);
182+
network2.addEdge(1, 5, 1);
183+
network2.addEdge(2, 4, 1);
184+
network2.addEdge(2, 6, 1);
185+
network2.addEdge(3, 5, 1);
186+
187+
// Add edges from right set to sink
188+
network2.addEdge(4, 7, 1);
189+
network2.addEdge(5, 7, 1);
190+
network2.addEdge(6, 7, 1);
191+
192+
int source2 = 0;
193+
int sink2 = 7;
194+
cout << "Maximum matching: " << network2.maxFlow(source2, sink2) << endl;
195+
network2.printFlowNetwork();
196+
197+
return 0;
198+
}

content/participation/abhi.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
### Abhi (Abhi)
2+
![Profile Picture](https://avatars.githubusercontent.com/u/33179956?v=4)
3+
- Full Stack Developer
4+
- CS Student
5+
- [Github Profile](https://github.com/cruiz24)
6+
7+
## Contribution
8+
- [(Dinic's algorithm for Maximum Flow)](.../CPP/algorithms/mathematical/dinics_algorithm.py)

0 commit comments

Comments
 (0)