b_vj_Hackers' Crackdown(预处理所有集合+检查合法集合后进行状态转移)
黑客想要整蛊有n台计算机的网络,每台计算机都运行着所有服务。对于每台计算机,你都可以选择一项服务,终止这台计算机和所有与它相邻计算机的该项服务。问最多能让多少种服务完全瘫痪(即没有任何计算及运行着这些服务)
思路:很难理解的题意
但简单来讲就是:有n个集合(集合与集合之间都拥有着对方的元素),你要尽量选出多个集合,使得这些集合的并集等于全集(这多个集合就是被暂停的服务,全集就是所有计算机都能被影响到)
#include<bits/stdc++.h>
using namespace std;
const int N=20;
int n,f[1<<N],t[N],conver[1<<N];
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int cs=1;
while (cin>>n, n) {
memset(f,0,sizeof f), memset(conver,0,sizeof conver), memset(t,0,sizeof t);
for (int i=0; i<n; i++) {
int c=0,x; cin>>c;
while (c--) cin>>x, t[i]|=(1<<x);
t[i]|=(1<<i);
}
int m=1<<n, all_conver=(1<<n)-1;
for (int i=0; i<m; i++)
for (int j=0; j<n; j++) if (i&(1<<j)) {
conver[i]|=t[j];
}
for (int i=0; i<m; i++) //枚举每一种状态(状态中的1的个数就是服务的个数)
for (int s=i; s; s=(s-1)&i) if (conver[s]==all_conver) //每个状态的子状态
f[i]=max(f[i], f[i^s]+1);
printf("Case %d: %d\n", cs++, f[all_conver]);
}
return 0;
}