Anniversary party POJ - 2342 (树形DP)

题目链接:

 POJ - 2342 

题目大意:给你n个人,然后每个人的重要性,以及两个人之间的附属关系,当上属选择的时候,他的下属不能选择,只要是两个人不互相冲突即可。然后问你以最高领导为起始点的关系网的重要性最大。

具体思路:简单树形DP,

dp[i][0]表示当前i点不选择,那么dp[i][0] =  sum( max(dp[to][1] ,dp[to][0] ) )(to为i的子节点)。

dp[i][1]表示当前i点选择, 那么dp[i][1] = dp[i][1] + sum(dp[to][0])(to为i的子节点)。

反思:可能会有多个起点的情况

AC代码:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<cmath>
 4 #include<vector>
 5 #include<cstring>
 6 #include<string>
 7 using namespace std;
 8 # define ll long long
 9 # define inf 0x3f3f3f3f
10 const int maxn = 2e5+100;
11 int  dp[maxn][2];
12 int in[maxn];
13 vector <int> Edge[maxn];
14 int vis[maxn];
15 void dfs(int u)
16 {
17     vis[u]=1;
18     for(int i=0; i<Edge[u].size(); i++)
19     {
20         int to=Edge[u][i];
21         if(vis[to])
22             continue;
23         dfs(to);
24         dp[u][1]=dp[u][1]+dp[to][0];
25         dp[u][0]=dp[u][0]+max(dp[to][0],dp[to][1]);
26     }
27 }
28 int main ( )
29 {
30     int n;
31     scanf("%d", &n);
32     for(int  i=1 ; i <=n ; i++ )
33     {
34         scanf("%d", &dp[i][1] );
35     }
36     int st,ed;
37     while(~scanf("%d %d",&st,&ed)&&(st+ed))
38     {
39         Edge[ed].push_back(st);
40         in[st]++;
41     }
42     int root;
43     for(int i=1; i<=n; i++)
44     {
45         if(!in[i])
46         {
47             root=i;
48             dfs(root);
49             break;
50         }
51     }
52     printf("%d\n",max(dp[root][0],dp[root][1]));
53     return 0;
54 }

 

转载于:https://www.cnblogs.com/letlifestop/p/10763620.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值