没有上司的舞会
题目描述
Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。
输入描述
第一行一个整数N。(1<=N<=6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0,0。
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0,0。
输出描述
输出最大的快乐指数。
样例输入
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
样例输出
5

#include<cstdio> int n,l,k,ans,jo[6005],re[6005]; struct ty { int data,fa,son,bro; } t[6005]; int max(int a,int b) { return a>b?a:b; } void find(int x,int y)//建树; { if(t[x].bro==0) t[x].bro=y; else find(t[x].bro,y); } int zhao(int x)//找根 { if (t[x].fa==0) return x; else zhao(t[x].fa); } void dp(int x) { if(!t[x].son&&!t[x].bro) {jo[x]=t[x].data;re[x]=0;}//是叶子节点的话,参加不参加。。 if(t[x].bro!=0) dp(t[x].bro); if(t[x].son!=0) dp(t[x].son); jo[t[x].fa]+=re[x]; //上司参加,直系下属不能参加; re[t[x].fa]+=max(jo[x],re[x]);//上司不参加,直系下属参不参加无所谓,找max } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) {scanf("%d",&t[i].data);jo[i]=t[i].data;}//读入数据,顺便把i参加的快乐值加到jo[i] scanf("%d%d",&l,&k); while(l!=0&&k!=0){//用的是兄弟孩子表示法 ; t[l].fa=k; if(t[k].son==0) t[k].son=l; else find(t[k].son,l); scanf("%d%d",&l,&k); } k=zhao(n);//找到根节点; dp(k); ans=max(jo[k],re[k]);//校长参不参加的最大值; printf("%d",ans); return 0; }
//人生第一次打树形DP,激动啊。。。。