139 lines
4.0 KiB
Java
139 lines
4.0 KiB
Java
|
/*This is a Java Program to Implement Hopcroft Karp Algorithm. The Hopcroft–Karp algorithm is an algorithm that takes as input a bipartite graph and produces as output a maximum cardinality matching – a set of as many edges as possible with the property that no two edges share an endpoint.*/
|
|||
|
|
|||
|
/**
|
|||
|
** Java Program to Implement Hopcroft Algorithm
|
|||
|
**/
|
|||
|
|
|||
|
import java.util.*;
|
|||
|
|
|||
|
/** Class Hopcroft **/
|
|||
|
public class Hopcroft
|
|||
|
{
|
|||
|
private final int NIL = 0;
|
|||
|
private final int INF = Integer.MAX_VALUE;
|
|||
|
private ArrayList<Integer>[] Adj;
|
|||
|
private int[] Pair;
|
|||
|
private int[] Dist;
|
|||
|
private int cx, cy;
|
|||
|
|
|||
|
/** Function BFS **/
|
|||
|
public boolean BFS()
|
|||
|
{
|
|||
|
Queue<Integer> queue = new LinkedList<Integer>();
|
|||
|
for (int v = 1; v <= cx; ++v)
|
|||
|
if (Pair[v] == NIL)
|
|||
|
{
|
|||
|
Dist[v] = 0;
|
|||
|
queue.add(v);
|
|||
|
}
|
|||
|
else
|
|||
|
Dist[v] = INF;
|
|||
|
Dist[NIL] = INF;
|
|||
|
while (!queue.isEmpty())
|
|||
|
{
|
|||
|
int v = queue.poll();
|
|||
|
if (Dist[v] < Dist[NIL])
|
|||
|
for (int u : Adj[v])
|
|||
|
if (Dist[Pair[u]] == INF)
|
|||
|
{
|
|||
|
Dist[Pair[u]] = Dist[v] + 1;
|
|||
|
queue.add(Pair[u]);
|
|||
|
}
|
|||
|
}
|
|||
|
return Dist[NIL] != INF;
|
|||
|
}
|
|||
|
/** Function DFS **/
|
|||
|
public boolean DFS(int v)
|
|||
|
{
|
|||
|
if (v != NIL)
|
|||
|
{
|
|||
|
for (int u : Adj[v])
|
|||
|
if (Dist[Pair[u]] == Dist[v] + 1)
|
|||
|
if (DFS(Pair[u]))
|
|||
|
{
|
|||
|
Pair[u] = v;
|
|||
|
Pair[v] = u;
|
|||
|
return true;
|
|||
|
}
|
|||
|
Dist[v] = INF;
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
/** Function to get maximum matching **/
|
|||
|
public int HopcroftKarp()
|
|||
|
{
|
|||
|
Pair = new int[cx + cy + 1];
|
|||
|
Dist = new int[cx + cy + 1];
|
|||
|
int matching = 0;
|
|||
|
while (BFS())
|
|||
|
for (int v = 1; v <= cx; ++v)
|
|||
|
if (Pair[v] == NIL)
|
|||
|
if (DFS(v))
|
|||
|
matching = matching + 1;
|
|||
|
return matching;
|
|||
|
}
|
|||
|
/** Function to make graph with vertices x , y **/
|
|||
|
public void makeGraph(int[] x, int[] y, int E)
|
|||
|
{
|
|||
|
Adj = new ArrayList[cx + cy + 1];
|
|||
|
for (int i = 0; i < Adj.length; ++i)
|
|||
|
Adj[i] = new ArrayList<Integer>();
|
|||
|
/** adding edges **/
|
|||
|
for (int i = 0; i < E; ++i)
|
|||
|
addEdge(x[i] + 1, y[i] + 1);
|
|||
|
}
|
|||
|
/** Function to add a edge **/
|
|||
|
public void addEdge(int u, int v)
|
|||
|
{
|
|||
|
Adj[u].add(cx + v);
|
|||
|
Adj[cx + v].add(u);
|
|||
|
}
|
|||
|
/** Main Method **/
|
|||
|
public static void main (String[] args)
|
|||
|
{
|
|||
|
Scanner scan = new Scanner(System.in);
|
|||
|
System.out.println("Hopcroft Algorithm Test\n");
|
|||
|
/** Make an object of Hopcroft class **/
|
|||
|
Hopcroft hc = new Hopcroft();
|
|||
|
/** Accept number of edges **/
|
|||
|
System.out.println("Enter number of edges\n");
|
|||
|
int E = scan.nextInt();
|
|||
|
int[] x = new int[E];
|
|||
|
int[] y = new int[E];
|
|||
|
hc.cx = 0;
|
|||
|
hc.cy = 0;
|
|||
|
System.out.println("Enter "+ E +" x, y coordinates ");
|
|||
|
for (int i = 0; i < E; i++)
|
|||
|
{
|
|||
|
x[i] = scan.nextInt();
|
|||
|
y[i] = scan.nextInt();
|
|||
|
hc.cx = Math.max(hc.cx, x[i]);
|
|||
|
hc.cy = Math.max(hc.cy, y[i]);
|
|||
|
}
|
|||
|
hc.cx += 1;
|
|||
|
hc.cy += 1;
|
|||
|
/** make graph with vertices **/
|
|||
|
hc.makeGraph(x, y, E);
|
|||
|
System.out.println("\nMatches : "+ hc.HopcroftKarp());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
Enter number of edges
|
|||
|
|
|||
|
11
|
|||
|
Enter 11 x, y coordinates
|
|||
|
0 0
|
|||
|
0 3
|
|||
|
1 0
|
|||
|
1 2
|
|||
|
1 4
|
|||
|
2 1
|
|||
|
3 0
|
|||
|
3 2
|
|||
|
3 3
|
|||
|
3 4
|
|||
|
4 2
|
|||
|
|
|||
|
Matches : 5
|