// 二分图匹配 hungary 算法
bool dfs( int i )
{
if( p[i] ) return false; else p[i] = true;
int j;
for( int k = h[i]; k; k = next[k] )
{
j = g[k];
if( !y[j] || dfs( y[j] ) )
return x[i] = j, y[j] = i, true;
}
return false;
}
// 二分图 Hopcroft-Karp 算法
bool bfs( )
{
memset( dis, -1, sizeof dis );
int i, j, clo = 0, open = 0;
bool ok = false;
for( i = 1; i <= n; i++ )
if( !x[i] ) dis[i] = 0, q[++open] = i;
while( clo < open )
{
i = q[++clo];
for( int k = h[i]; k; k = next[k] )
{
j = g[k];
if( !y[j] ) ok = true;
else if( dis[ y[j] ] == -1 ) dis[ y[j] ] = dis[i]+1, q[++open] = y[j];
}
}
return ok;
}
bool dfs( int i )
{
int j;
for( int k = h[i]; k; k = next[k] )
{
j = g[k];
if( !y[j] || dis[ y[j] ] == dis[i]+1 && dfs( y[j] ) )
return x[i] = j, y[j] = i, true;
}
return false;
}