using
System;
using
System.Collections.Generic;
using
System.Linq;
class
HopcroftKarp
{
const
int
NIL = 0;
const
int
INF =
int
.MaxValue;
static
void
Main()
{
int
n = 4;
int
m = 4;
var
g =
new
BipGraph(n, m);
g.addEdge(1, 2);
g.addEdge(1, 3);
g.addEdge(2, 1);
g.addEdge(3, 2);
g.addEdge(4, 2);
g.addEdge(4, 4);
Console.WriteLine(
"Size of maximum matching is "
+
g.hopcroftKarp());
}
class
BipGraph
{
private
readonly
int
m;
private
readonly
int
n;
private
readonly
List<
int
>[] adj;
private
int
[] pairU;
private
int
[] pairV;
private
int
[] dist;
public
BipGraph(
int
m,
int
n)
{
this
.m = m;
this
.n = n;
adj =
new
List<
int
>[m + 1];
for
(
int
i = 0; i <= m; i++)
{
adj[i] =
new
List<
int
>();
}
}
public
void
addEdge(
int
u,
int
v)
{
adj[u].Add(v);
}
public
int
hopcroftKarp()
{
pairU = Enumerable.Repeat(NIL, m + 1).ToArray();
pairV = Enumerable.Repeat(NIL, n + 1).ToArray();
dist = Enumerable.Repeat(0, m + 1).ToArray();
int
result = 0;
while
(bfs())
{
for
(
int
u = 1; u <= m; u++)
{
if
(pairU[u] == NIL && dfs(u))
{
result++;
}
}
}
return
result;
}
private
bool
bfs()
{
var
Q =
new
Queue<
int
>();
for
(
int
u = 1; u <= m; u++)
{
if
(pairU[u] == NIL)
{
dist[u] = 0;
Q.Enqueue(u);
}
else
{
dist[u] = INF;
}
}
dist[NIL] = INF;
while
(Q.Count > 0)
{
int
u = Q.Dequeue();
if
(dist[u] < dist[NIL])
{
foreach
(
int
v
in
adj[u])
{
if
(dist[pairV[v]] == INF)
{
dist[pairV[v]] = dist[u] + 1;
Q.Enqueue(pairV[v]);
}
}
}
}
return
dist[NIL] != INF;
}
private
bool
dfs(
int
u)
{
if
(u != NIL)
{
foreach
(
int
v
in
adj[u])
{
if
(dist[pairV[v]] == dist[u] + 1)
{
if
(dfs(pairV[v]))
{
pairV[v] = u;
pairU[u] = v;
return
true
;
}
}
}
dist[u] = INF;
return
false
;
}
return
true
;
}
}
}