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;
}
posted @ 2020-11-06 14:31  童年の波鞋  阅读(65)  评论(0编辑  收藏  举报