标签:can scan set 组合 pair 子集 blog -- names
题解:
首先将相邻点进行二进制,保存在p[i]中
然后将不同组合的p[i]组合的值记录下来,保存在cover[i]中
然后从小到大进行dp
s0为集合s的子集
if(cover[ s0 ] == all - 1) f[s] = max( f[s], f[s ^ s0] + 1);
代码:
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define pii pair<int,int> const int INF = 1000000000; const int maxn = 1 << 16; int n, m, x; int p[ 16 ], cover[ maxn ]; int f[ maxn ]; int main() { int Case = 1; while( ~scanf( "%d", &n ) && n ) { memset( p, 0, sizeof( p ) ); for( int i = 0; i < n; i ++ ) { scanf( "%d", &m ); p[ i ] = ( 1 << i ); while( m -- ) { scanf( "%d", &x ); p[ i ] |= ( 1 << x ); } } int ALL = 1 << n; for( int s = 0; s < ALL; s ++ ) { cover[ s ] = 0; for( int i = 0; i < n; i ++ ) if( s & ( 1 << i ) ) cover[ s ] |= p[ i ]; } for( int s = 0; s < ALL; s ++ ) { f[ s ] = 0; for( int s0 = s; s0; s0 = ( s0 - 1 ) & s ) { if( cover[ s0 ] == ALL - 1 ) f[ s ] = max( f[ s ], f[ s ^ s0 ] + 1 ); } } printf( "Case %d: %d\n", Case ++, f[ ALL - 1 ] ); } return 0; }
标签:can scan set 组合 pair 子集 blog -- names
原文地址:http://www.cnblogs.com/byene/p/6123984.html