ZROIの#1007

ZROIの#1007

また、タイトルを行うには非常に低い見えます。

慎重に考慮すべきことは、非常に見つかった(coool \)\事を:

私は彼がカバーする最小の独立したセットを作ることではないことを祈ります...

図セットに別々のカバーがペアワイズ点の各サブセットが通信していないいくつかのサブセットに分割されていることをいいます。

次に、(2 ^ n個\)\レコードの列挙されたサブセットが、その後、別に設定された独立したセット、ではありません\(DP \)

あなたはそれを行います\(F_S \)があるポイントセットを表します\(S \)最小設定時間の独立したカバレッジ。

明らかに、それは別のセットからのものであってもよい各時間から転送されたサブセットがかかり、ある\(分\)端(最短最長経路)にします。

最終的な答えがされ(F_ {U} -1 \)\\(U \)が完了した作品です。なぜマイナス1ああ?

最長の道路は、エッジの数があるので、ああ...

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#define MEM(x,y) memset ( x , y , sizeof ( x ) )
#define rep(i,a,b) for (int i = (a) ; i <= (b) ; ++ i)
#define per(i,a,b) for (int i = (a) ; i >= (b) ; -- i)
#define pii pair < int , int >
#define one first
#define two second
#define rint read<int>
#define int long long
#define pb push_back

using std::queue ;
using std::set ;
using std::pair ;
using std::max ;
using std::min ;
using std::priority_queue ;
using std::vector ;
using std::swap ;
using std::sort ;
using std::unique ;
using std::greater ;

template < class T >
    inline T read () {
        T x = 0 , f = 1 ; char ch = getchar () ;
        while ( ch < '0' || ch > '9' ) {
            if ( ch == '-' ) f = - 1 ;
            ch = getchar () ;
        }
       while ( ch >= '0' && ch <= '9' ) {
            x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ;
            ch = getchar () ;
       }
   return f * x ;
}

const int N = 20 ;
const int MAXS = 1 << 20 ;
int n , m , ans , s[N] ;
int g[MAXS] , f[MAXS] , cnt ;
bool e[N][N] ;

inline bool judge () {
    rep ( i , 1 , cnt ) rep ( j , 1 , cnt )
        if ( e[s[i]][s[j]] || e[s[j]][s[i]] ) return false ;
    return true ;
}

signed main (int argc , char * argv[]) {
    n = rint () ; m = rint () ;
    rep ( i , 1 , m ) {
        int u = rint () , v = rint () ;
        e[u][v] = e[v][u] = true ;
    }
    int maxsize = 1 << n ;
    for (int i = 0 ; i < maxsize ; ++ i) {
        cnt = 0 ;
        for (int j = 0 ; j < n ; ++ j)
            if ( i & ( 1 << j ) )
                s[++cnt] = j + 1 ;
        g[i] = judge () ;
    }
    MEM ( f , 0x7f ) ; f[0] = 0 ;
    for (int i = 0 ; i < maxsize ; ++ i) {
        for (int j = i ; j ; j = ( j - 1 ) & i )
            if ( ! g[j] ) continue ;
            else f[i] = min ( f[i] , f[i^j] + 1 ) ;
    }
    printf ("%lld\n" , f[maxsize-1] - 1 ) ;
    return 0 ;
}

おすすめ

転載: www.cnblogs.com/Equinox-Flower/p/11572397.html