uva11825Hacker's Crackdown

题意:题意很费解,大意是有N台电脑,每台电脑有N(N<=16)个服务,一个黑客可以在每台电脑上跑一个(只能跑一个)让一种服务崩溃的病毒,并且这个病毒可以传播到跟他邻接的顶点,问最多这个黑客可以让多少个服务崩溃?(每台电脑上都是N个不同服务,每台电脑上跑的都是一样的服务,让一个服务崩溃是让所有的电脑上的这个服务崩溃)

分析:要想到题目对应的数学模型:把n个集合P1,p2,...,pn分成尽量多组使得每组中的所有集合的并集等于全集,这里集合Pi就是计算机i及其相邻计算机的集合,每组对应一种服务。书上说用二进制表示,我觉得有些地方还是不很理解。。。

View Code
 1 #include <stdio.h>
 2 #include <iostream>
 3 using namespace std;
 4 const int MAXN = (1<<16);
 5 int p[20], cover[MAXN], f[MAXN];
 6 #define DEBUG
 7 int main(){
 8     int n, m, i, j, x, cas=1;
 9     while(scanf("%d", &n)!=EOF && n){
10         for(i=0; i<n; i++){
11             scanf("%d", &m);
12             p[i]=1<<i;
13             for(j=0; j<m; j++){
14                 scanf("%d", &x);
15                 p[i] |=(1<<x);
16             }
17         }
18         int s;
19         for(s=0; s<(1<<n); s++){
20             cover[s]=0;
21             for(i=0; i<n; i++)
22                 if(s&(1<<i)) cover[s]|=p[i];
23         }
24         f[0]=0;
25         int ALL = (1<<n) - 1;
26         for(s=1; s<(1<<n); s++){
27             f[s] = 0;
28             for(int so=s; so; so=(so-1)&s)
29                 if(cover[so]==ALL && f[s]<f[s^so]+1) f[s]=f[s^so]+1;    //s^so是对应的补集还是什么别的?不理解啊
30         }
31         printf("Case %d: %d\n", cas++, f[ALL]);
32     }
33     return 0;
34 }

 

posted @ 2013-02-14 15:24  ChrisZZ  阅读(221)  评论(0编辑  收藏  举报