题目链接:

 POJ - 2342 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

题目大意:给你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 }

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄