
- DSA - Home
- DSA - Overview
- DSA - Environment Setup
- DSA - Algorithms Basics
- DSA - Asymptotic Analysis
- Data Structures
- DSA - Data Structure Basics
- DSA - Data Structures and Types
- DSA - Array Data Structure
- DSA - Skip List Data Structure
- Linked Lists
- DSA - Linked List Data Structure
- DSA - Doubly Linked List Data Structure
- DSA - Circular Linked List Data Structure
- Stack & Queue
- DSA - Stack Data Structure
- DSA - Expression Parsing
- DSA - Queue Data Structure
- DSA - Circular Queue Data Structure
- DSA - Priority Queue Data Structure
- DSA - Deque Data Structure
- Searching Algorithms
- DSA - Searching Algorithms
- DSA - Linear Search Algorithm
- DSA - Binary Search Algorithm
- DSA - Interpolation Search
- DSA - Jump Search Algorithm
- DSA - Exponential Search
- DSA - Fibonacci Search
- DSA - Sublist Search
- DSA - Hash Table
- Sorting Algorithms
- DSA - Sorting Algorithms
- DSA - Bubble Sort Algorithm
- DSA - Insertion Sort Algorithm
- DSA - Selection Sort Algorithm
- DSA - Merge Sort Algorithm
- DSA - Shell Sort Algorithm
- DSA - Heap Sort Algorithm
- DSA - Bucket Sort Algorithm
- DSA - Counting Sort Algorithm
- DSA - Radix Sort Algorithm
- DSA - Quick Sort Algorithm
- Matrices Data Structure
- DSA - Matrices Data Structure
- DSA - Lup Decomposition In Matrices
- DSA - Lu Decomposition In Matrices
- Graph Data Structure
- DSA - Graph Data Structure
- DSA - Depth First Traversal
- DSA - Breadth First Traversal
- DSA - Spanning Tree
- DSA - Topological Sorting
- DSA - Strongly Connected Components
- DSA - Biconnected Components
- DSA - Augmenting Path
- DSA - Network Flow Problems
- DSA - Flow Networks In Data Structures
- DSA - Edmonds Blossom Algorithm
- DSA - Maxflow Mincut Theorem
- Tree Data Structure
- DSA - Tree Data Structure
- DSA - Tree Traversal
- DSA - Binary Search Tree
- DSA - AVL Tree
- DSA - Red Black Trees
- DSA - B Trees
- DSA - B+ Trees
- DSA - Splay Trees
- DSA - Range Queries
- DSA - Segment Trees
- DSA - Fenwick Tree
- DSA - Fusion Tree
- DSA - Hashed Array Tree
- DSA - K-Ary Tree
- DSA - Kd Trees
- DSA - Priority Search Tree Data Structure
- Recursion
- DSA - Recursion Algorithms
- DSA - Tower of Hanoi Using Recursion
- DSA - Fibonacci Series Using Recursion
- Divide and Conquer
- DSA - Divide and Conquer
- DSA - Max-Min Problem
- DSA - Strassen's Matrix Multiplication
- DSA - Karatsuba Algorithm
- Greedy Algorithms
- DSA - Greedy Algorithms
- DSA - Travelling Salesman Problem (Greedy Approach)
- DSA - Prim's Minimal Spanning Tree
- DSA - Kruskal's Minimal Spanning Tree
- DSA - Dijkstra's Shortest Path Algorithm
- DSA - Map Colouring Algorithm
- DSA - Fractional Knapsack Problem
- DSA - Job Sequencing with Deadline
- DSA - Optimal Merge Pattern Algorithm
- Dynamic Programming
- DSA - Dynamic Programming
- DSA - Matrix Chain Multiplication
- DSA - Floyd Warshall Algorithm
- DSA - 0-1 Knapsack Problem
- DSA - Longest Common Sub-sequence Algorithm
- DSA - Travelling Salesman Problem (Dynamic Approach)
- Hashing
- DSA - Hashing Data Structure
- DSA - Collision In Hashing
- Disjoint Set
- DSA - Disjoint Set
- DSA - Path Compression And Union By Rank
- Heap
- DSA - Heap Data Structure
- DSA - Binary Heap
- DSA - Binomial Heap
- DSA - Fibonacci Heap
- Tries Data Structure
- DSA - Tries
- DSA - Standard Tries
- DSA - Compressed Tries
- DSA - Suffix Tries
- Treaps
- DSA - Treaps Data Structure
- Bit Mask
- DSA - Bit Mask In Data Structures
- Bloom Filter
- DSA - Bloom Filter Data Structure
- Approximation Algorithms
- DSA - Approximation Algorithms
- DSA - Vertex Cover Algorithm
- DSA - Set Cover Problem
- DSA - Travelling Salesman Problem (Approximation Approach)
- Randomized Algorithms
- DSA - Randomized Algorithms
- DSA - Randomized Quick Sort Algorithm
- DSA - Karger’s Minimum Cut Algorithm
- DSA - Fisher-Yates Shuffle Algorithm
- Miscellaneous
- DSA - Infix to Postfix
- DSA - Bellmon Ford Shortest Path
- DSA - Maximum Bipartite Matching
- DSA Useful Resources
- DSA - Questions and Answers
- DSA - Selection Sort Interview Questions
- DSA - Merge Sort Interview Questions
- DSA - Insertion Sort Interview Questions
- DSA - Heap Sort Interview Questions
- DSA - Bubble Sort Interview Questions
- DSA - Bucket Sort Interview Questions
- DSA - Radix Sort Interview Questions
- DSA - Cycle Sort Interview Questions
- DSA - Quick Guide
- DSA - Useful Resources
- DSA - Discussion
Maximum Bipartite Matching
A maximum bipartite graph is a type of bipartite graph that has the highest possible number of edges between two sets of vertices.
A bipartite graph is a graph where the set of vertices can be divided into two groups, such that no two vertices within the same group are directly connected. The maximum bipartite graph is one where every vertex in the first group is connected to every vertex in the second group.
If one group has m vertices and the other has n vertices, the total number of edges in the maximum bipartite graph is:
Emax = m n
Properties of Maximum Bipartite Graphs
Maximum bipartite graphs have the following properties:
- It has two separate groups of vertices, and edges only connect vertices from different groups.
- The total number of edges is the maximum possible, which is the product of the number of vertices in each group.
- Since there are no connections within the same group, it never contains odd-length cycles.
- The graph can always be colored using just two colorsone for each group of vertices.
- Maximum bipartite graphs are useful in real-world applications like job assignments, networking, and resource allocation.
Example of Maximum Bipartite Graph
Consider the following bipartite graph with four vertices:
A -- B | | C -- D
In this example, the graph has two groups of vertices: {A, C} and {B, D}. The maximum bipartite graph would have the following edges:
- A -- B
- A -- D
- C -- B
- C -- D
There are four edges in total, which is the maximum possible for this graph.
Algorithms for Maximum Bipartite Matching
There are several algorithms to find the maximum bipartite matching in a graph:
- Hopcroft-Karp Algorithm
- Ford-Fulkerson Algorithm
- Hungarian Algorithm
- Edmonds-Karp Algorithm
- Augmenting Path Algorithm
- Network Flow Algorithm
Code to Find Maximum Bipartite Matching using Hopcroft-Karp Algorithm
Now, let's look at the steps to find the maximum bipartite matching in a graph using the Hopcroft-Karp algorithm:
1. Create a bipartite graph with two sets of vertices. 2. Initialize an empty matching between the two sets. 3. While there is an augmenting path in the graph: a. Find an augmenting path using a matching algorithm. b. Update the matching by adding or removing edges along the path. 4. Return the maximum matching found.
Let's look at an example of code to find the maximum bipartite matching in a graph using the Hopcroft-Karp algorithm:
// C program to find maximum matching in a bipartite graph #include <stdio.h> #include <stdbool.h> #define M 6 #define N 6 bool bpm(int bpGraph[M][N], int u, bool seen[], int matchR[]) { for (int v = 0; v < N; v++) { if((bpGraph[u][v] && !seen[v])) { seen[v] = true; if ((matchR[v] < 0 || bpm(bpGraph, matchR[v], seen, matchR))) { matchR[v] = u; return true; } } } return false; } int maxBPM(int bpGraph[M][N]) { int matchR[N]; for(int i = 0; i < N; i++) matchR[i] = -1; int result = 0; for(int u = 0; u < M; u++) { bool seen[N]; for(int i = 0; i < N; i++) seen[i] = false; if(bpm(bpGraph, u, seen, matchR)) result++; } return result; } int main() { int bpGraph[M][N] = { {0, 1, 1, 0, 0, 0}, {1, 0, 0, 1, 0, 0}, {0, 0, 1, 0, 0, 0}, {0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 1} }; printf("Maximum matching is %d\n", maxBPM(bpGraph)); return 0; }
Output
Maximum matching is 5
// C++ program to find maximum matching in a bipartite graph #include <iostream> #include <vector> using namespace std; #define M 6 #define N 6 bool bpm(vector<vector<int>> &bpGraph, int u, vector<bool> &seen, vector<int> &matchR) { for (int v = 0; v < N; v++) { if(bpGraph[u][v] && !seen[v]) { seen[v] = true; if (matchR[v] < 0 || bpm(bpGraph, matchR[v], seen, matchR)) { matchR[v] = u; return true; } } } return false; } int maxBPM(vector<vector<int>> &bpGraph) { vector<int> matchR(N, -1); int result = 0; for(int u = 0; u < M; u++) { vector<bool> seen(N, false); if(bpm(bpGraph, u, seen, matchR)) result++; } return result; } int main() { vector<vector<int>> bpGraph = { {0, 1, 1, 0, 0, 0}, {1, 0, 0, 1, 0, 0}, {0, 0, 1, 0, 0, 0}, {0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 1} }; cout << "Maximum matching is " << maxBPM(bpGraph) << endl; return 0; }
Output
Maximum matching is 5
// Java program to find maximum matching in a bipartite graph import java.util.*; public class MaximumBipartiteMatching { static final int M = 6; static final int N = 6; static boolean bpm(int bpGraph[][], int u, boolean seen[], int matchR[]) { for (int v = 0; v < N; v++) { if(bpGraph[u][v]==1 && !seen[v]) { seen[v] = true; if (matchR[v] < 0 || bpm(bpGraph, matchR[v], seen, matchR)) { matchR[v] = u; return true; } } } return false; } static int maxBPM(int bpGraph[][]) { int matchR[] = new int[N]; Arrays.fill(matchR, -1); int result = 0; for(int u = 0; u < M; u++) { boolean seen[] = new boolean[N]; if(bpm(bpGraph, u, seen, matchR)) result++; } return result; } public static void main(String[] args) { int bpGraph[][] = { {0, 1, 1, 0, 0, 0}, {1, 0, 0, 1, 0, 0}, {0, 0, 1, 0, 0, 0}, {0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 1} }; System.out.println("Maximum matching is " + maxBPM(bpGraph)); } }
Output
Maximum matching is 5
# Python program to find maximum matching in a bipartite graph M = 6 N = 6 def bpm(bpGraph, u, seen, matchR): for v in range(N): if bpGraph[u][v] and not seen[v]: seen[v] = True if matchR[v] < 0 or bpm(bpGraph, matchR[v], seen, matchR): matchR[v] = u return True return False def maxBPM(bpGraph): matchR = [-1] * N result = 0 for u in range(M): seen = [False] * N if bpm(bpGraph, u, seen, matchR): result += 1 return result if __name__ == "__main__": bpGraph = [ [0, 1, 1, 0, 0, 0], [1, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1] ] print("Maximum matching is", maxBPM(bpGraph))
Output
Maximum matching is 5
Applications of Maximum Bipartite Matching
Maximum bipartite matching algorithms have several real-world applications:
- Job Assignments: Assigning tasks to workers based on their skills and availability.
- Networking: Routing data packets through a network to optimize traffic flow.
- Resource Allocation: Allocating resources like time, money, or equipment to maximize efficiency.
- Marriage Matching: Pairing individuals based on preferences and compatibility.
- Project Planning: Scheduling tasks and dependencies to complete projects on time.
These applications demonstrate the importance of maximum bipartite matching algorithms in solving complex optimization problems.
Time Complexity of Maximum Bipartite Matching
The time complexity of finding the maximum bipartite matching in a graph using the Hopcroft-Karp algorithm is O(sqrt(V) * E), where V is the number of vertices and E is the number of edges in the graph. This algorithm is efficient for sparse graphs with a large number of vertices.
Conclusion
In this tutorial, we learned about maximum bipartite graphs and how to find the maximum bipartite matching in a graph using various algorithms. We also explored the properties and applications of maximum bipartite graphs in real-world scenarios. By understanding these concepts, you can solve a wide range of optimization problems efficiently.