zoukankan      html  css  js  c++  java
  • B

    B - Wealthy Family
    Time Limit:10000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

    Description

    Download as PDF

    While studying the history of royal families, you want to know how wealthy each family is. While you have various 'net worth' figures for each individual throughout history, this is complicated by double counting caused by inheritance. One way to estimate the wealth of a family is to sum up the net worth of a set of k people such that no one in the set is an ancestor of another in the set. The wealth of the family is the maximum sum achievable over all such sets of k people. Since historical records contain only the net worth of male family members, the family tree is a simple tree in which every male has exactly one father and a non-negative number of sons. You may assume that there is one person who is an ancestor of all other family members.

    Input

    The input consists of a number of cases. Each case starts with a line containing two integers separated by a space: N ( 1$ le$N$ le$150, 000), the number of people in the family, and k ( 1$ le$k$ le$300), the size of the set. The next N lines contain two non-negative integers separated by a space: the parent number and the net worth of person i ( 1$ le$i$ le$N). Each person is identified by a number between 1 and N, inclusive. There is exactly one person who has no parent in the historical records, and this will be indicated with a parent number of `0'. The net worths are given in millions and each family member has a net worth of at least 1 million and at most 1 billion.

    Output

    For each case, print the maximum sum (in millions) achievable over all sets of k people satisfying the constraints given above. If it is impossible to choose a set of k people without violating the constraints, print 'impossible' instead.

    Sample Input

     
    5 3
    0 10
    1 15
    1 25
    1 35
    4 45
    3 3
    0 10
    1 10
    2 10
    

    Sample Output

     
    85
    impossible
    

    题目大意:给n个点,每个点有一个权值,要求选k个点,这k个点任意一个点不能为其他点的父节点,求最大总权值。
    思路:树形DP。ex[i]代表从开始遍历到某点x及其子节点(包括x)选i个点可以得到的最大 总权值,now[i]代表从开始遍历到某点x及其子节点(不包括x)选i个点可以得到的最大总权值,函数一开始的时候ex是代表遍历到x之前的选i个点可 以得到的最大总权值,那么在dfs算出now之后,ex[i] = max(now[i], ex[i-1] + a)就可以保证没有选的两个点是不符合要求的。

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 const int MAXN = 150010;
     5 
     6 int head[MAXN], next[MAXN], to[MAXN];
     7 int a[MAXN];
     8 int ecnt, n, k;
     9 int ans[310];
    10 
    11 inline void addEdge(int u, int v) {
    12     to[ecnt] = v;
    13     next[ecnt] = head[u]; head[u] = ecnt++;
    14     //printf("%d->%d
    ",u,v);
    15 }
    16 
    17 inline void init() {
    18     memset(head, 0, sizeof(head));
    19     memset(ans, 255, sizeof(ans));
    20     ecnt = 2;
    21     int f;
    22     for(int i = 1; i <= n; ++i) {
    23         scanf("%d%d", &f, &a[i]);
    24         addEdge(f, i);
    25     }
    26 }
    27 
    28 inline void _max(int &a, const int &b) {
    29     if(a < b) a = b;
    30 }
    31 
    32 void dfs(int u, int *ex) {
    33     int *now = new int[310];
    34     for(int i = 0; i <= k; ++i) now[i] = ex[i];
    35     for(int p = head[u]; p; p = next[p]) {
    36         dfs(to[p], now);
    37     }
    38     ex[0] = 0;
    39     for(int i = k; i > 0; --i) {
    40         ex[i] = now[i];
    41         if(ex[i-1] != -1) {
    42             _max(ex[i], ex[i-1] + a[u]);
    43         }
    44     }
    45     delete [] now;
    46 }
    47 
    48 int main() {
    49     while(scanf("%d%d", &n, &k) != EOF) {
    50         init();
    51         dfs(0,ans);
    52         if(ans[k] == -1) puts("impossible");
    53         else printf("%d
    ", ans[k]);
    54     }
    55     return 0;
    56 }

    By Oyking

  • 相关阅读:
    python的函数
    Python的条件语句和循环语句
    Python的输入与输出
    Python变量和类型
    Python的运算符
    Python的注释
    pycharm基本使用
    推特史上最大规模黑客入侵案:17岁问题少年的隐秘人生
    进程和线程的区别及线程的介绍
    python接口自动化42
  • 原文地址:https://www.cnblogs.com/scnuacm/p/3199979.html
Copyright © 2011-2022 走看看