UVA11825(二进制子集枚举)

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;
}


猜你喜欢

转载自blog.csdn.net/qq_37325947/article/details/80585725