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;
    }
  • 相关阅读:
    python与数据库(SQLServer、MySQL、Redis、MongoDB)
    网络表示学习 图神经网络资料整理
    Java学习笔记 算法 Algorithms Fourth Edition
    word2vec 代码解读
    爬虫python的世界
    mac 字幕生成工具
    CS224W Analysis of Networks
    SNAP macos
    python基础代码
    Keras笔记
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6551460.html
Copyright © 2011-2022 走看看