/* **************************************** *****
Bipartite Graph Matching (hopcroft-Carp'sAlgorithm).
Initialization: G [] [] adjacent matrix
Call: res = maxmatch (); NX, NY to initialize !!!
Time Complexity: O (V ^ 0.5 E)
Suitable for binary matching with large data volumes
**************************************** ****** */
Const Int Maxn = 3001 ;
Const Int INF = 1 < 28 ;
Int G [maxn] [maxn], MX [maxn], my [maxn], NX, NY;
Int DX [maxn], Dy [maxn], DIS;
Bool VST [maxn];
Bool Searchp ()
{
Queue < Int > Q;
DIS = INF;
Memset (dx, - 1 , Sizeof (Dx ));
Memset (dy, - 1 , Sizeof (Dy ));
For ( Int I = 0 ; I < NX; I ++ )
If (MX [I] =- 1 )
{
Q. Push (I );
DX [I] = 0 ;
}
While ( ! Q. Empty ())
{
Int U = Q. Front ();
Q. Pop ();
If (Dx [u] > Dis) Break ;
For ( Int V = 0 ; V < NY; V ++ )
If (G [u] [v] && Dy [v] =- 1 )
{
Dy [v] = DX [u] + 1 ;
If (My [v] =- 1 ) Dis = Dy [v];
Else
{
DX [my [v] = Dy [v] + 1 ;
Q. Push (my [v]);
}
}
}
Return DIS ! = INF;
}
Bool DFS ( Int U)
{
For ( Int V = 0 ; V < NY; V ++ )
If ( ! VST [v] && G [u] [v] && Dy [v] = DX [u] + 1 )
{
VST [v] = 1 ;
If (My [v] ! =- 1 && Dy [v] = Dis) Continue ;
If (My [v] =- 1 | DFS (my [v])
{
My [v] = U;
MX [u] = V;
Return 1 ;
}
}
Return 0 ;
}
Int Maxmatch ()
{
Int Res = 0 ;
Memset (MX, - 1 , Sizeof (MX ));
Memset (my, - 1 , Sizeof (My ));
While (Searchp ())
{
Memset (VST, 0 , Sizeof (VST ));
For ( Int I = 0 ; I < NX; I ++ )
If (MX [I] =- 1 && DFS (I) res ++ ;
}
Return Res;
}