zoukankan      html  css  js  c++  java
  • poj 2342 hdu 1520【树形dp】

    poj 2342

    给出每个顶点的happy值,还有若干组两个顶点L,K关系,表示K是L的上司。求当K、L不同时出现时获得的happy值的最大和。

    设dp[u][0]表示不选u结点时获得的最大值,dp[u][1]表示选u结点时获得的最大值。则有:

       dp[u][0]+=max(dp[v][0],dp[v][1]),dp[u][1]+=dp[v][0](u为v的父节点)

    当父亲节点用有向边连向子节点时,会形成一颗树,自然就只有一个根。那么从根开始dfs就行了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<vector>
     5 #include<algorithm>
     6 using namespace std;
     7 const int maxn = 6200;
     8 int dp[maxn][2], vis[maxn], a[maxn];
     9 vector<int> tree[maxn];
    10 int N;
    11 
    12 void Init()
    13 {
    14     for (int i = 1; i <= N; i++) {
    15         cin >> a[i];
    16         tree[i].clear(), vis[i] = 0;
    17     }
    18     int L, K;
    19     while (cin>>L>>K)
    20     {
    21         if (L == 0 && K == 0) break;
    22         tree[K].push_back(L);
    23         vis[L] = 1;
    24     }
    25     tree[0].clear();//找根
    26     for(int i=1;i<=N;i++)
    27         if (!vis[i]) {
    28             tree[0].push_back(i);
    29             break;//只有一个根,找到后就break
    30         }
    31 }
    32 
    33 void dfs(int u)
    34 {
    35     dp[u][0] = 0;
    36     dp[u][1] = a[u];
    37     for (int i = 0; i < tree[u].size(); i++)
    38     {
    39         int v = tree[u][i];
    40         dfs(v);
    41         dp[u][0] += max(dp[v][0], dp[v][1]);
    42         dp[u][1] += dp[v][0];
    43     }
    44 }
    45 
    46 void Solve()
    47 {
    48     int root = tree[0][0];
    49     dfs(root);
    50     cout << max(dp[root][0], dp[root][1]) << endl;
    51 }
    52 
    53 int main()
    54 {
    55     while (cin>>N)
    56     {
    57         Init();
    58         Solve();
    59     }
    60     return 0;
    61 }
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<vector>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 const int maxn=6200;
     9 int dp[maxn][2],rat[maxn],f[maxn],vis[maxn];
    10 vector<int> tree[maxn];
    11 
    12 void dfs(int u)
    13 {
    14     vis[u]=1;
    15     dp[u][0]=0;
    16     dp[u][1]=rat[u];
    17     int len=tree[u].size();
    18     for(int i=0;i<len;i++){
    19         int v=tree[u][i];
    20         if(vis[v]) continue;
    21         dfs(v);
    22         dp[u][0]+=max(dp[v] [1],dp[v][0]);
    23         dp[u][1]+=dp[v][0];
    24     }
    25 }
    26 
    27 int main()
    28 {
    29     int N;
    30     while(scanf("%d",&N)==1)
    31     {
    32         for(int i=1;i<=N;i++){
    33             scanf("%d",&rat[i]);
    34             vis[i]=0;f[i]=-1;
    35             tree[i].clear();
    36         }
    37         int a,b;
    38         while(scanf("%d%d",&a,&b))
    39         {
    40             if(a==0&&b==0) break;
    41             f[a]=b;
    42             tree[b].push_back(a);
    43         }
    44         int root;
    45         for(int i=1;i<=N;i++){
    46             if(f[i]==-1){
    47                 root=i;
    48                 break;
    49             }
    50         }
    51         dfs(root);
    52         cout<<max(dp[root][0],dp[root][1])<<endl;
    53     }
    54     return 0;
    55 }
    又写了一遍
  • 相关阅读:
    awk
    tac
    cat
    less
    more
    head
    vim
    linux安装redis
    Redis for Python开发手册
    Python3.x标准模块库目录
  • 原文地址:https://www.cnblogs.com/zxhyxiao/p/7580515.html
Copyright © 2011-2022 走看看