思路
这是一个无源无汇的最小割问题.或者说叫"无向图全局最小割".
一个很暴力的思想就是枚举任意两个点作为源点和汇点.
复杂度大概是,但是由于跑不到上界,还是可以过的.
如果对这个复杂度不满意,可以枚举源点,其他点向汇点连边,复杂度为,优秀得多.
你还可以使用二进制思想,枚举每一位,将所有点分成两部分,源点向一部分连边,剩下的向汇点连边,复杂度大概为.
才50,
可以忽略.(我没有试过,还不知道对不对,有错误请指出)
还有一种的做法Stoer Wagner专门求无向图全局最小割.感兴趣的同学请上网查阅资料.
因为我也不会
代码
最暴力的做法(*/ω\*)
#include<bits/stdc++.h>
using namespace std;
//#define LOCAL
#define MAXN 9999
#define MAXM 999999
int N, M, Ti;
int hd[MAXN], nxt[MAXM], to[MAXM], val[MAXM], tot(1);
int d[MAXN]; queue<int> Q;
int S, T;
char bf[1<<21], *p;
int read( int len = INT_MAX ){
int ans(0);
while( !isdigit(*p) ){
p++; if ( *p == '\0' ) return -12345;
}
while( isdigit(*p) && len-- ) ans = ans * 10 + ((*p) ^ '0'), p++;
return ans;
}
void Add( int x, int y, int z ){
nxt[++tot] = hd[x]; hd[x] = tot; to[tot] = y; val[tot] = z;
nxt[++tot] = hd[y]; hd[y] = tot; to[tot] = x; val[tot] = 0;
}
bool BFS(){
while( !Q.empty() ) Q.pop();
memset( d, 0, sizeof d );
Q.push( S ); d[S] = 1;
while( !Q.empty() ){
int t(Q.front()); Q.pop();
for ( int i = hd[t]; i; i = nxt[i] ){
if ( val[i] && !d[to[i]] ){
Q.push(to[i]); d[to[i]] = d[t] + 1;
if ( to[i] == T ) return 1;
}
}
}
return 0;
}
int DFS( int x, int fl ){
if ( x == T ) return fl;
int res(fl), k;
for ( int i = hd[x]; i && res; i = nxt[i] ){
if ( val[i] && d[to[i]] == d[x] + 1 ){
k = DFS( to[i], min( val[i], res ) );
if ( !k ) d[to[i]] = 0;
res -= k; val[i] -= k; val[i ^ 1] += k;
}
}
return fl - res;
}
int main(){
#ifdef LOCAL
freopen( "1.in", "r", stdin );
#endif
memset( bf, 0, sizeof bf );
bf[fread( bf, 1, 1 << 21, stdin )] = '\0'; p = bf;
while( ( N = read() ) >= 0 ){
M = read();
memset( hd, 0, sizeof hd ); tot = 1;
for ( int i = 1; i <= N; ++i ) Add( i, i + N, 1 );
for ( int i = 1; i <= M; ++i ){
int x, y; x = read() + 1; y = read() + 1;
Add( x + N, y, INT_MAX ), Add( y + N, x, INT_MAX );
}
int res(N);
for ( int i = 1; i <= N; ++i )
for ( int j = i + 1; j <= N; ++j ){
for ( int k = 2; k <= tot; k += 2 ) val[k] += val[k ^ 1], val[k ^ 1] = 0;
S = i + N; T = j;
bool flg(0);
for ( int k = hd[S]; k; k = nxt[k] )
if ( to[k] == T ){
flg = 1; break;
}
if ( flg ) continue;
int cur(0), t;
while( BFS() ) while( ( t = DFS( S, N ) ) ) cur += t;
res = min( res, cur );
}
printf( "%d\n", res );
}
return 0;
} 
京公网安备 11010502036488号