zoukankan      html  css  js  c++  java
  • ZOJ 3201

    Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu


    Description

    You're given a tree with weights of each node, you need to find the maximum subtree of specified size of this tree.

    Tree Definition
    A tree is a connected graph which contains no cycles.

    Input

    There are several test cases in the input.

    The first line of each case are two integers N(1 <= N <= 100), K(1 <= K <= N), where N is the number of nodes of this tree, and K is the subtree's size, followed by a line with N nonnegative integers, where the k-th integer indicates the weight of k-th node. The following N - 1 lines describe the tree, each line are two integers which means there is an edge between these two nodes. All indices above are zero-base and it is guaranteed that the description of the tree is correct.

    Output

    One line with a single integer for each case, which is the total weights of the maximum subtree.

    Sample Input

    3 1
    10 20 30
    0 1
    0 2
    3 2
    10 20 30
    0 1
    0 2
    

    Sample Output

    30
    40
    

    Source

    ZOJ Monthly, May 2009


    树状DP~
    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define maxn 105
    int n,k,dp[maxn][maxn],val[maxn];
    vector <int> edge[maxn];
    void dfs(int u,int y)
    {
      dp[u][1] = val[u];
      for(int i = 0;i < edge[u].size();i ++)
      {
        int v = edge[u][i];
        if(v == y) continue;
        dfs(v, u);
        for(int j = k;j > 0;j --)  //相似01背包
         for(int p = 0;p < j;p ++)
        {
         dp[u][j] = max(dp[u][j], dp[u][j-p] + dp[v][p]);
        }
      }
    }
    int main()
    {
        int a, b,ans;
        while(scanf("%d%d", &n, &k) != EOF)
        {
          ans = -1;
          memset(dp, -1, sizeof(dp));
          for(int i = 0;i < n;i ++)
          edge[i].clear();
          for(int i = 0;i < n;i ++)
          scanf("%d", &val[i]);
          for(int i = 0;i < n-1;i ++)
          {
            scanf("%d%d",&a,&b);
            edge[a].push_back(b);
            edge[b].push_back(a);
          }
          dfs(0, -1);
          for(int i = 0;i < n;i ++)
          ans = max(ans, dp[i][k]);
          printf("%d
    ", ans);
        }
        return 0;
    }
    


  • 相关阅读:
    虚拟机的Linux 安装 若干问题(一)
    理解JavaScript的闭包
    javascript里面的引用类型和值类型
    javascript导入自定义模块
    简单了解下CAP定理与BASE定理
    背包问题之完全背包
    背包问题之多重背包
    背包问题之0-1背包
    搜索算法初步总结
    谈一谈“回溯法“
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6852692.html
Copyright © 2011-2022 走看看