没有上司的舞会
这道题我知道的写法有用多叉树的也有用二叉树的来写,二叉树的话要用到左孩子右兄弟算法。二叉树的写法我感觉相对比多叉树还是很难写的。
用一个f数组储存这个人来还是不来,0表示不来,1表示来,这样的话
f[i][1]=f[k][0]; i表示这个人,k表示他所有的下属,如果他来他的下属就都不会来。
f[i][0]=max( f[k][0] , f[k][1] ) 表示如果他来,那么他的下属来不来都可以,我们取最大的
这个就是核心的方程了,剩下的看代码应该都能解决,如果不会多叉树自行百度。
题目描述
某大学有N个职员,编号为1~N。他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。
输入格式:
第一行一个整数N。(1<=N<=6000)
接下来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<iostream> #include<string> #include<cstdio> using namespace std; int N,c[6010],a[6010],b[6010][3010]; int f[6010][2],re=0; //============================================== void make() { int x,y; memset(c,1,sizeof(c)); for(int i=1;i<=N-1;i++){ scanf("%d%d",&x,&y); b[y][++b[y][0]]=x; c[x]=false; } scanf("%d%d",&x,&y); for(int i=1;i<=N;i++){ if(c[i]){ re=i; break; } } } //============================================== void dfs(int i) { if(b[i][0]==0){ f[i][1]=a[i]; return; } for(int k=1;k<=b[i][0];k++){ dfs(b[i][k]); f[i][1]+=f[ b[i][k] ][0]; f[i][0]+=max( f[b[i][k]][0] , f[b[i][k]][1] ); } f[i][1]+=a[i]; } //============================================== void init() { cin>>N; for(int i=1;i<=N;i++){ scanf("%d",&a[i]); } make(); dfs(re); printf("%d",max(f[re][0],f[re][1])); } //============================================== int main() { init(); system("pause"); return 0; }