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 }
    又写了一遍
  • 相关阅读:
    POJ 1469 COURSES 二分图最大匹配
    POJ 1325 Machine Schedule 二分图最大匹配
    USACO Humble Numbers DP?
    SGU 194 Reactor Cooling 带容量上下限制的网络流
    POJ 3084 Panic Room 求最小割
    ZOJ 2587 Unique Attack 判断最小割是否唯一
    Poj 1815 Friendship 枚举+求最小割
    POJ 3308 Paratroopers 最小点权覆盖 求最小割
    1227. Rally Championship
    Etaoin Shrdlu
  • 原文地址:https://www.cnblogs.com/zxhyxiao/p/7580515.html
Copyright © 2011-2022 走看看