1380 没有上司的舞会 40分
1380 没有上司的舞会
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 钻石 Diamond
题目描述 Description
Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。
输入描述 Input Description
第一行一个整数N。(1<=N<=6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0,0。
输出描述
Output Description
输出最大的快乐指数。
样例输入
Sample Input
7
1
1
1
1v
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
样例输出
Sample Output
5
数据范围及提示
Data Size & Hint
各个测试点1s
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 6 using namespace std; 7 const int N=6001; 8 9 struct node{ 10 int f; 11 int w; 12 }; 13 node e[N]; 14 15 int wi[N]; 16 17 bool cmp(node a,node b) 18 { 19 return a.w>b.w; 20 } 21 22 int main() 23 { 24 int n; 25 cin>>n; 26 for(int i=1;i<=n;i++) 27 { 28 cin>>e[i].w; 29 } 30 int q,w; 31 for(int i=1;i<=n-1;i++) 32 { 33 cin>>q>>w; 34 e[q].f=w; 35 } 36 cin>>q>>w; 37 sort(e+1,e+n+1,cmp); 38 int ans=0; 39 for(int i=1;i<=n+1;i++) 40 { 41 ans+=e[i].w; 42 if(i!=0) 43 { 44 e[e[i].f].w=0; 45 } 46 } 47 cout<<ans; 48 return 0; 49 }
正解,树形dp:
/* by http://www.cnblogs.com/xiaoningmeng/p/5865623.html 树形dp 用vector建图,找到没有上司的那个点,从这个点开始dfs 而每个点都有两种情况,一是选择这个点取得的最大值和不选取得最大值,dp[i][1]表示选择这个点时的最大值, dp[i][0]表示不选这个点取得最大值,方程式为 dp[x][0]+=max(dp[i][1],dp[i][0]);dp[x][1]+=dp[i][0]; */ #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> using namespace std; vector <int> G[6010]; int n,x,y; int dp[6010][2]; int r[6010]; int boss[6010]; void dfs(int x) { for(int j=0;j<G[x].size();j++) { int i=G[x][j]; dfs(i);//递归到最子节点 dp[x][0]+=max(dp[i][1],dp[i][0]);//if(当前点不取)其值+=其子节点取与不取的较大者 dp[x][1]+=dp[i][0];//if(当前点取)其值+=其子节点不取的情况 } dp[x][1]+=r[x];//若取 +上该节点的值 } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&r[i]); while(scanf("%d%d",&x,&y)==2,x||y) { G[y].push_back(x); boss[x]=y; } for(int i=1;i<=n;i++) if(boss[i]==0) { dfs(i); printf("%d",max(dp[i][1],dp[i][0])); break; } return 0; } /* 7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0 5 */