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\n" , f[maxsize-1] - 1 ) ;
return 0 ;
}
May you return with a young heart after years of fighting.