思路

这是一个无源无汇的最小割问题.或者说叫"无向图全局最小割".
一个很暴力的思想就是枚举任意两个点作为源点和汇点.
复杂度大概是,但是由于跑不到上界,还是可以过的.
如果对这个复杂度不满意,可以枚举源点,其他点向汇点连边,复杂度为,优秀得多.
你还可以使用二进制思想,枚举每一位,将所有点分成两部分,源点向一部分连边,剩下的向汇点连边,复杂度大概为.才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;
}