Miracle Corporations has a number of system services running in a distributed computer system whichis a prime target for hackers. The system is basically a set of N computer nodes with each of themrunning a set of N services. Note that, the set of services running on every node is same everywherein the network. A hacker can destroy a service by running a specialized exploit for that service in allthe nodes.One day, a smart hacker collects necessary exploits for all these N services and launches an attackon the system. He finds a security hole that gives him just enough time to run a single exploit in eachcomputer. These exploits have the characteristic that, its successfully infects the computer where itwas originally run and all the neighbor computers of that node.Given a network description, find the maximum number of services that the hacker can damage.InputThere will be multiple test cases in the input file. A test case begins with an integer N (1 ≤ N ≤ 16),the number of nodes in the network. The nodes are denoted by 0 to N − 1. Each of the followingN lines describes the neighbors of a node. Line i (0 ≤ i < N) represents the description of node i.The description for node i starts with an integer m (Number of neighbors for node i), followed by mintegers in the range of 0 to N − 1, each denoting a neighboring node of node i.The end of input will be denoted by a case with N = 0. This case should not be processed.OutputFor each test case, print a line in the format, ‘Case X: Y ’, where X is the case number & Y is themaximum possible number of services that can be damaged.Sample Input32 1 22 0 22 0 141 11 01 31 20Sample OutputCase 1: 3Case 2: 2
感觉用二进制枚举子集的时候很神奇,一个for就枚举出了一个集合的所有子集。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#define ls 2*rt
#define rs 2*rt+1
#define lson ls,L,mid
#define rson rs,mid+1,R
#define ll long long
using namespace std;
typedef pair<int,int> pii;
const ll inf = 0x3f3f3f3f;
/*void dis(int a[], int n){
printf("总数为%d个\n",n);
for(int i = 0; i < n; i++) cout<<a[i]<<", ";
cout<<endl<<"------------------"<<endl;
}*/
const int mx = (1<<16)+10;
//stack<int>s;
/*void da(int x){
cout<<x<<"的二进制"<<endl;
while(x){
//cout<<x%2<<",";
s.push(x%2);
x/=2;
}
while(!s.empty()){
cout<<s.top()<<",";
s.pop();
}
puts("");
} */
int c[mx],s[mx],f[mx];
int n;
int main(){
int ca = 0,m,te;
while(scanf("%d",&n) && n){
for(int i = 0; i < n; i++){
scanf("%d",&m);
c[i] = 0;
c[i] |= 1<<i;
while(m--){
scanf("%d",&te);
c[i] |= (1<<te);
}
}
// memset(s,0,sizeof(s));
for(int i = 1; i < 1<<n;i++){
s[i] = 0;
for(int k = 0; k < n; k++){
if(i&(1<<k))
s[i] |= c[k];
}
}
int all = (1<<n)-1;
memset(f,0,sizeof(f));
for(int i = 1; i < 1<<n;i++){
for(int g = i;g;g = (g-1)&i){
if(s[g]==all){ //这里写错
f[i] = max(f[i],f[i^g]+1);
}
}
}
printf("Case %d: %d\n",++ca,f[all]);
}
return 0;
}