This blog covers three powerful categories of problems:
- Flow Networks (Max Flow / Min Cut)
- Graph Matching (Maximum Matching, Bipartite Matching)
- Bipartite Graph Applications (Coloring, Assignment, Scheduling)
1️⃣ Flow Networks (Max Flow / Min Cut)
A flow network is a directed graph where each edge has a capacity, and we want to push as much “flow” from a source (s) to a sink (t) as possible.
- Max Flow = Maximum possible flow from
s
→t
. - Min Cut = Smallest set of edges that, if removed, disconnect
s
fromt
. - Ford-Fulkerson / Edmonds-Karp Algorithm: Repeatedly send augmenting paths until no more flow can be added.
Java Implementation (Edmonds-Karp using BFS)
import java.util.*; class MaxFlow { private int n; private int[][] capacity; private List<Integer>[] adj; public MaxFlow(int n) { this.n = n; capacity = new int[n][n]; adj = new List[n]; for (int i = 0; i < n; i++) adj[i] = new ArrayList<>(); } public void addEdge(int u, int v, int cap) { capacity[u][v] += cap; // Handle multiple edges adj[u].add(v); adj[v].add(u); // Residual graph } private int bfs(int s, int t, int[] parent) { Arrays.fill(parent, -1); parent[s] = s; Queue<int[]> q = new LinkedList<>(); q.add(new int[]{s, Integer.MAX_VALUE}); while (!q.isEmpty()) { int[] cur = q.poll(); int node = cur[0], flow = cur[1]; for (int next : adj[node]) { if (parent[next] == -1 && capacity[node][next] > 0) { parent[next] = node; int newFlow = Math.min(flow, capacity[node][next]); if (next == t) return newFlow; q.add(new int[]{next, newFlow}); } } } return 0; } public int maxFlow(int s, int t) { int flow = 0; int[] parent = new int[n]; int newFlow; while ((newFlow = bfs(s, t, parent)) > 0) { flow += newFlow; int cur = t; while (cur != s) { int prev = parent[cur]; capacity[prev][cur] -= newFlow; capacity[cur][prev] += newFlow; cur = prev; } } return flow; } }
📌 Example Problems:
- Maximum Bipartite Matching (via Flow)
- Network Bandwidth Optimization
- Airline Traffic Scheduling
- Project Assignment
2️⃣ Graph Matching
Graph Matching = selecting edges such that no two edges share a vertex.
- Maximum Matching = maximum number of matched pairs.
- Bipartite Matching = matching only across two sets (e.g., jobs ↔ workers).
-
Can be solved via:
- DFS Augmenting Path (Hungarian Algorithm)
- Max Flow (Reduction of Matching → Flow)
Example: Bipartite Matching with DFS
class BipartiteMatching { private int n, m; private List<Integer>[] graph; private int[] matchR; private boolean[] seen; public BipartiteMatching(int n, int m) { this.n = n; // left partition this.m = m; // right partition graph = new List[n]; for (int i = 0; i < n; i++) graph[i] = new ArrayList<>(); } public void addEdge(int u, int v) { graph[u].add(v); // Edge from left u → right v } private boolean bpm(int u) { for (int v : graph[u]) { if (seen[v]) continue; seen[v] = true; if (matchR[v] == -1 || bpm(matchR[v])) { matchR[v] = u; return true; } } return false; } public int maxMatching() { matchR = new int[m]; Arrays.fill(matchR, -1); int result = 0; for (int u = 0; u < n; u++) { seen = new boolean[m]; if (bpm(u)) result++; } return result; } }
📌 Example Problems:
- Job Assignment (workers → jobs).
- Stable Marriage Problem.
- Course Scheduling (students → projects).
3️⃣ Bipartite Graphs
A graph is bipartite if nodes can be divided into two disjoint sets such that every edge connects a node in set A to set B.
Checking if a Graph is Bipartite (using BFS Coloring)
public boolean isBipartite(int[][] graph) { int n = graph.length; int[] color = new int[n]; Arrays.fill(color, -1); for (int i = 0; i < n; i++) { if (color[i] == -1) { Queue<Integer> q = new LinkedList<>(); q.add(i); color[i] = 0; while (!q.isEmpty()) { int u = q.poll(); for (int v : graph[u]) { if (color[v] == -1) { color[v] = 1 - color[u]; q.add(v); } else if (color[v] == color[u]) { return false; } } } } } return true; }
📌 Example Problems:
- Graph Coloring
- Team Formation
- Odd-Cycle Detection
🧠 Key Takeaways
- Flow Networks → Max flow, min cut, traffic optimization.
- Matching → Job assignment, stable marriage, bipartite matching.
- Bipartite Graphs → Graph coloring, odd cycle detection, DFS/BFS-based verification.
These patterns power advanced graph algorithms that solve real-world optimization and scheduling problems.
Top comments (0)