zoukankan      html  css  js  c++  java
  • UVa 1220 Hali-Bula的晚会(树的最大独立集)

    https://vjudge.net/problem/UVA-1220

    题意:

    公司里有n个人形成一个树状结构,即除了老板以外每个员工都有唯一的直属上司。要求选尽量多的人,但不能同时选择一个人和他的直属上司。输出最多能选多少人并判断是否唯一。

    思路:

    树的最大独立集问题。就是需要额外判定是否是唯一的。

    因为输入的都是人名,所以首先就是用map容器来处理,上下属的关系就用vector容器来处理。

    d[u][1]表示以u为根的子树中,选u点能得到的最大人数,f[u][1]判断这种方案是否唯一。

    d[u][0]表示以u为根的子树中,不选u点能得到的最大人数,f[u][0]判断这种方案是否唯一。

    状态转移方程其实不是很难。首先分析d[u][1],因为u选了,所以u的子结点都不能选,它的子节点的状态只能是这样的,所以此时d[u][1]=sum(d[v][0]|v是u的子节点)。容易想到f[v][0]都为唯一时,f[u][1]才是唯一的。

    其次是d[u][0],此时u的子节点可选可不选,所以我们需要挑选出更大的那个,每个子节点都是这样处理,最后像上面那样加起来就可以了。转移方程就是d[u][0]=sum(max(d[v][0],d[v][1]))。方案唯一值的判定和上面是一样的,就是分析你所挑选的更大的那个。

    根结点值依赖于子节点,所以需要用DFS来处理

     1 #include<iostream> 
     2 #include<string>
     3 #include<cstring>
     4 #include<vector>
     5 #include<algorithm>
     6 #include<map>
     7 using namespace std;
     8 
     9 const int maxn = 200+5;
    10 
    11 int n, cnt;
    12 string s1, s2;
    13 
    14 int d[maxn][2], f[maxn][2];
    15 
    16 map<string, int> id;
    17 vector<int> sons[maxn];
    18 
    19 
    20 void solve(int u)
    21 {
    22     //最下属的只有两种情况
    23     if (sons[u].size() == 0)
    24     {
    25         d[u][0] = 0;
    26         d[u][1] = 1;
    27         return;
    28     }
    29     int k = sons[u].size();
    30 
    31     for (int i = 0; i < k; i++)
    32     {
    33         int son = sons[u][i];
    34         //树形的DFS
    35         solve(son);
    36         d[u][1] += d[son][0];
    37         //一旦有子节点不唯一,它也不唯一
    38         if (!f[son][0])    f[u][1] = 0;
    39         //u不选时,它的子节点可选可不选,此时需要选个大的
    40         d[u][0] += max(d[son][1], d[son][0]);  
    41 
    42         //判断是否唯一
    43         if (d[son][0]>d[son][1] && !f[son][0])             f[u][0] = 0;
    44         else if (d[son][1] > d[son][0] && !f[son][1] )     f[u][0] = 0;
    45         else if (d[son][0] == d[son][1])                   f[u][0] = 0;
    46 
    47     }
    48     ++d[u][1];
    49 }
    50 
    51 int main()
    52 {
    53     //freopen("D:\txt.txt", "r", stdin);
    54     while (cin >> n && n)
    55     {
    56         memset(d, 0, sizeof(d));
    57         //初始化都为唯一
    58         for (int i = 0; i <= n; i++)
    59             f[i][1] = f[i][0] = 1;
    60         id.clear();
    61         for (int i = 1; i <= n; i++)
    62             sons[i].clear();
    63         cnt = 0;
    64 
    65         cin >> s1;
    66         id[s1] = ++cnt;
    67         for (int i = 1; i < n; i++)
    68         {
    69             cin >> s1 >> s2;
    70             if (!id[s1])  id[s1] = ++cnt;
    71             if (!id[s2])  id[s2] = ++cnt;
    72             sons[id[s2]].push_back(id[s1]);
    73          }
    74 
    75         solve(1);
    76 
    77         if (d[1][0] == d[1][1])  printf("%d No
    ", d[1][0]);
    78         else if (d[1][0] > d[1][1])  printf("%d %s
    ", d[1][0], !f[1][0] ? "No" : "Yes");
    79         else  printf("%d %s
    ", d[1][1], !f[1][1] ? "No" : "Yes");
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    03 java中的基本数据类型和运算符
    02 Eclipse安装
    01 HelloWorld
    express不是内部或外部命令
    win10 内存或系统资源不足,无法打开PPT
    win 10中解决“此文件在另外一个进程中运行”的问题
    后台查找密码暴力破解
    DVWA--全等级暴力破解(Burte Force)
    DVWA简单搭建
    破解版
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6375696.html
Copyright © 2011-2022 走看看