zoukankan      html  css  js  c++  java
  • uva 11825

    Miracle Corporations has a number of system services running in a distributed computer system which is a prime target for hackers. The system is basically a set of N computer nodes with each of them running a set of N services. Note that, the set of services running on every node is same everywhere in the network. A hacker can destroy a service by running a specialized exploit for that service in all the nodes. One day, a smart hacker collects necessary exploits for all these N services and launches an attack on the system. He finds a security hole that gives him just enough time to run a single exploit in each computer. These exploits have the characteristic that, its successfully infects the computer where it was 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. Input There 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 following N 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 m integers 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. Output For each test case, print a line in the format, ‘Case X: Y ’, where X is the case number & Y is the maximum possible number of services that can be damaged. Sample Input 3 2 1 2 2 0 2 2 0 1 4 1 1 1 0 1 3 1 2 0 Sample Output Case 1: 3 Case 2: 2

    学到了新知识:枚举子集 for(int S0 = S; S0 ; S0 = (S0-1) & S ) 但是状态我也没想出来

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 20;
    
    int n, m, Case;
    int dp[1 << N], p[N], cover[1 << N]; 
    int main()
    {
        while(scanf("%d", &n))
        {
            if(!n) break;
            memset(p ,0 ,sizeof(p));
            memset(dp ,0 ,sizeof(dp));
            memset(cover ,0 ,sizeof(cover));
            for(int i = 0; i < n; ++i)
            {
                p[i] = (1 << i); //p[i] 表示i电脑能占领的集合 
                int m, x; scanf("%d", &m);
                while(m--)
                {
                    scanf("%d", &x); 
                    p[i] |= (1 << x);
                }
            }
            int All = (1 << n);
            for(int S = 0; S < All; ++S)
                for(int i = 0; i < n; ++i) if(S & (1 << i))
                    cover[S] |= p[i]; //占领S这些电脑能覆盖的集合 
            for(int i = 0; i < All; ++i) 
                for(int j = i; j ; j = (j - 1) & i)
                    if(cover[j] == All - 1) dp[i] = max(dp[i], dp[i ^ j] + 1);
            //如果自己的一个子集是全集,那么可以随便选 
            printf("Case %d: %d
    ", ++Case, dp[All - 1]);
        }
        return 0;
    }
  • 相关阅读:
    237. Delete Node in a Linked List
    430. Flatten a Multilevel Doubly Linked List
    707. Design Linked List
    83. Remove Duplicates from Sorted List
    160. Intersection of Two Linked Lists
    426. Convert Binary Search Tree to Sorted Doubly Linked List
    142. Linked List Cycle II
    类之间的关系
    初始化块
    明确类和对象
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6551460.html
Copyright © 2011-2022 走看看