zoukankan      html  css  js  c++  java
  • ZROI#1007

    ZROI#1007

    也是看起来非常不可做的一个题.

    仔细思考,发现了一个很(cooooool)的事情:

    他是不是让我求最小独立集覆盖...

    一个独立集覆盖是指把图划分成若干个子集,每个子集里的点两两互不连通.

    然后你(2^n)枚举子集,记录是不是一个独立集,然后在独立集上(DP).

    你就令(f_S)表示点集为(S)时的最小独立集覆盖.

    显然,每次可以从它一个是独立集的子集转移过来,取一个(min)就完了(最长路最短).

    最后的答案是(f_{U}-1),其中(U)是全集.为什么减一啊?

    因为最长路是边数啊...

    #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
    " , f[maxsize-1] - 1 ) ;
        return 0 ;
    }
    
    May you return with a young heart after years of fighting.
  • 相关阅读:
    POJ1985 树的直径(BFS
    POJ2186 强连通分量+缩点
    AIM Tech Round 5C. Rectangles 思维
    POJ2553 汇点个数(强连通分量
    hdu6370 并查集+dfs
    UVALive 7037:The Problem Needs 3D Arrays(最大密度子图)
    POJ 3155:Hard Life(最大密度子图)
    HDU 5527:Too Rich(DFS+贪心)***
    HDU 5534:Partial Tree(完全背包)***
    Wannafly挑战赛1:Treepath(DFS统计)
  • 原文地址:https://www.cnblogs.com/Equinox-Flower/p/11572397.html
Copyright © 2011-2022 走看看