zoukankan      html  css  js  c++  java
  • 黑客攻击 UVa11825

    http://www.cnblogs.com/acm-bingzi/p/3272898.html

    Hackers’ Crackdown

    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 computer nodes with each of them running a set of Nservices. 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 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 lines describes the neighbors of a node. Line i (0<=i<N) represents the description of node i. The description for node starts with an integer (Number of neighbors for node i), followed by integers in the range of 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

    Output for Sample Input

    Case 1: 3

    Case 2: 2

    题目大意:(黑客的攻击)假设你是一个黑客,侵入了了一个有着n台计算机(编号为0,1,…,n-1)的网络。一共有n种服务,每台计算机都运行着所有的服务。对于每台计算机,你都可以选择一项服务,终止这台计算机和所有与它相邻计算机的该项服务(如果其中一些服务已经停止,则这些服务继续处于停止状态)。你的目标是让尽量多的服务器完全瘫痪(即:没有任何计算机运行该项服务)

    输入格式:输入包含多组数据。每组数据的第一行为整数n(1<=n<=16);以下n行每行描述一台计算机的相邻计算机,其中第一个数m为相邻计算机个数,接下来的m个整数位这些计算机的编号。输入结束标志为n=0。

    输出格式:对于每组数据,输出完全瘫痪的服务器的最大数量。

    分析:

      本题的数学模型是:把n个集合p1,p2,…pn分成尽量多组,使得每组中所有集合的并集等于全集。这里的集合P就是计算机 i 及其相邻计算机的集合,每组对应于题目中的一项服务。注意到n很小,可以用二进制法表示这些集合,即在代码中,每个集合P实际上是一个非负整数。输入的部分代码如下:

    for(int i=0;i<n;i++){
        int m,x;
        scanf("%d",&m);
        P[i] = 1<<i;
        while(m--) { scanf("%d",&x); P[i] |= (1<<x); }
    }

      为了方便,我们用cover(S)表示若干P的集合S中所有Pi 的并集(二级制表示),即这些Pi 在数值上“按位或”。

    for(int S = 0; S < (1<<n); S++){
        cover[S] = 0;
        for(int i=0;i<n;i++)
            if(S & (1<<i)) cover[S] |= P[i];
    }

    想到这样的动态规划:用f(S)表示子集S最多可以分成多少组,则

      f(S) = max{f(S-S0)+1 |S0是S的子集,cover[S0]等于全集}

    如何理解这个方程呢?

    S0是S的子集,并且S0可以覆盖全部的点,也就是说集合S0至少可以分成一组

    把S0分成一组,剩下的是集合S-S0,最多可以分成f(S-S0)组

    选出其中最大的,再加上S0的一组,就是f(S)

    这里有一个重要的技巧:枚举S的子集S0。详见下面代码。

    复制代码
    int ALL = (1<<n) - 1;
    for(int S = 1 ;S< (1<<n); S++){
        f[S] = 0;
        for(int S0 = S; S0; S0 = (S0-1)&S)
            if(cover[S0] == ALL) f[S] = max(f[S], f[S^S0]+1);
    }
    printf("Case %d: %d
    ",++kase,f[ALL]);
    复制代码

    完整代码如下:

    复制代码
     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 
     5 const int maxn = 16;
     6 int n, P[maxn], cover[1<<maxn], f[1<<maxn];
     7 int main() {
     8   int kase = 0;
     9   while(scanf("%d", &n) == 1 && n) {
    10     for(int i = 0; i < n; i++) {
    11       int m, x;
    12       scanf("%d", &m);
    13       P[i] = 1<<i;
    14       while(m--) { scanf("%d", &x); P[i] |= (1<<x); }
    15     }
    16     for(int S = 0; S < (1<<n); S++) {
    17       cover[S] = 0;
    18       for(int i = 0; i < n; i++)
    19         if(S & (1<<i)) cover[S] |= P[i];
    20     }
    21     f[0] = 0;
    22     int ALL = (1<<n) - 1;
    23     for(int S = 1; S < (1<<n); S++) {
    24       f[S] = 0;
    25       for(int S0 = S; S0; S0 = (S0-1)&S)
    26         if(cover[S0] == ALL) f[S] = max(f[S], f[S^S0]+1);
    27     }
    28     printf("Case %d: %d
    ", ++kase, f[ALL]);
    29   }
    30   return 0;
    31 }
    复制代码

    注意:位运算符的优先级比较低,注意加括号

  • 相关阅读:
    Jmeter之http性能测试实战 非GUI模式压测 NON-GUI模式 结果解析TPS——干货(十一)
    UI Recorder 自动化测试 回归原理(九)
    UI Recorder 自动化测试 录制原理(八)
    UI Recorder 自动化测试 整体架构(七)
    UI Recorder 自动化测试 配置项(六)
    UI Recorder 自动化测试 工具栏使用(五)
    UI Recorder 自动化测试 回归测试(四)
    UI Recorder 自动化测试 录制(三)
    UI Recorder 自动化测试工具安装问题疑难杂症解决(二)
    UI Recorder 自动化测试安装教程(一)
  • 原文地址:https://www.cnblogs.com/FuTaimeng/p/5413728.html
Copyright © 2011-2022 走看看