这是一个全局最小割的题:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std ;
const int INF = 999999999 ;
const int MAXN = 505 ;
int map[MAXN][MAXN] , low[MAXN] , vis[MAXN] , last , pre , N , flag ;
bool bfs() ;
void prim( int ) ;
int stoerwagner( int ) ;
int main()
{
int m , n , start , end , w , ans ;
while( scanf( "%d%d" , & n , & m ) != EOF )
{
N = n ;
memset( map , 0 , sizeof( map ) ) ;
while( m -- )
{
scanf( "%d%d%d" , & start , & end , & w ) ;
map[start][end] += w ;
map[end][start] += w ;
}
flag = bfs() ;
if( flag ){
ans = stoerwagner( n ) ;
cout << ans << endl ;
}
else cout << 0 << endl ;
}
return 0 ;
}
bool bfs()
{
flag = 0 ;
memset( vis , 0 , sizeof( vis ) ) ;
queue < int > q ;
vis[0] = 1 ;
q.push( 0 ) ;
while( !q.empty() )
{
int temp = q.front() ;
q.pop() ;
for( int i = 0 ; i < N ; i ++ )
if( map[temp][i] > 0 && !vis[i] )
{
q.push( i ) ;
vis[i] = 1 ;
}
}
for( int i = 0 ; i < N ; i ++ )
if( !vis[i] ) return false ;
return true ;
}
int stoerwagner( int n )
{
int Min = INF , temp , tmp ;
while( n > 1 )
{
prim( n ) ;
temp = 0 ;
for( int j = 0 ; j < N ; j ++ )
if( map[j][last] ) temp += map[j][last] ;
if( temp < Min && temp > 0 ) Min = temp ;
n -- ;
map[pre][last] = map[last][pre] = 0 ;
temp = min( pre , last ) ;
tmp = max( pre , last ) ;
for( int j = 0 ; j < N ; j ++ )
{
if( map[tmp][j] ) {
map[temp][j] += map[tmp][j] ;
map[tmp][j] = 0 ;
}
if( map[j][tmp] ) {
map[j][temp] += map[j][tmp] ;
map[j][tmp] = 0 ;
}
}
}
return Min ;
}
void prim( int n )
{
memset( vis , 0 , sizeof( vis ) ) ;
memset( low , 0 , sizeof( low ) ) ;
low[0] = INF ;
for( int i = 1 ; i <= n ; i ++ )
{
int Max = 0 , mark ;
for( int j = 0 ; j < N ; j ++ )
if( !vis[j] && low[j] > Max ) {
Max = low[j] ;
mark = j ;
}
vis[mark] = 1 ;
if( i == n - 1 ) pre = mark ;
if( i == n ) last = mark ;
for( int j = 0 ; j < N ; j ++ )
if( !vis[j] ) low[j] += map[mark][j] ;
}
}