ACM模版
最小边割集
int max_flow(int n, int mat[][MAXN], int source, int sink)
{
int v[MAXN], c[MAXN], p[MAXN], ret = 0 , i, j;
for (;;)
{
for (i = 0 ; i < n; i++)
{
v[i] = c[i] = 0 ;
}
for (c[source] = inf; ;)
{
for (j = -1 , i = 0 ; i < n; i++)
{
if (!v[i] && c[i] && (j == -1 || c[i] > c[j]))
{
j = i;
}
}
if (j < 0 )
{
return ret;
}
if (j == sink)
{
break ;
}
for (v[j] = 1 , i = 0 ; i < n; i++)
{
if (mat[j][i] > c[i] && c[j] > c[i])
{
c[i] = mat[j][i] < c[j] ? mat[j][i] : c[j], p[i] = j;
}
}
}
for (ret += j = c[i = sink]; i != source; i = p[i])
{
mat[p[i]][i] -= j, mat[i][p[i]] += j;
}
}
}
int min_edge_cut(int n, int mat[][MAXN], int source, int sink, int set[][2 ])
{
int m 0 [MAXN][MAXN], m [MAXN][MAXN], i, j, k, l, ret = 0 , last ;
if (source == sink)
{
return -1 ;
}
for (i = 0 ; i < n; i++)
{
for (j = 0 ; j < n; j++)
{
m 0 [i][j] = (mat[i][j] != 0 );
}
}
for (i = 0 ; i < n; i++)
{
for (j = 0 ; j < n; j++)
{
m [i][j] = m 0 [i][j];
}
}
last = max_flow(n, m , source, sink);
for (k = 0 ; k < n && last ; k++)
{
for (l = 0 ; l < n && last ; l++)
{
if (m 0 [k][l])
{
for (i = 0 ; i < n + n; i++)
{
for (j = 0 ; j < n + n; j++)
{
m [i][j] = m 0 [i][j];
}
}
m [k][l] = 0 ;
if (max_flow(n, m , source, sink) < last )
{
set[ret][0 ] = k;
set[ret++][1 ] = l;
m 0 [k][l] = 0 ;
last --;
}
}
}
}
return ret;
}