A - Anniversary party

要有一个庆祝乌拉尔州立大学80周年。这所大学有一个员工的层次结构。这意味着主管的关系形成一个树在特列季亚科夫校长”。为了使党的滑稽的每一个,校长不希望员工和他或她的直属主管到场。人事办公室评估每个员工的欢乐,所以每个人都有一些数(等级)连接到他或她。你的任务是与客人欢宴评级的最大金额列出客人。

输入

员工编号从1到N的第一行输入包含一个数N = N = 6 < 1 < 000。接下来的N行包含相应员工的欢乐度。欢乐的评级是一个整数的范围从128到127 -。之后去行,描述一个主管关系树。每行树规范的形式:

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<cstring>
#include<vector>
using namespace std;
const int M=1e5+10;
bool vis[M];//标记
int dp[M][2];//两种状态
vector<int>e[M];

void dfs(int v){
	for(int i=0;i<e[v].size();i++){//找v有几个孩子 
		int u=e[v][i];
		dfs(u); 
		dp[v][0]+=max(dp[u][1],dp[u][0]);
		dp[v][1]+=dp[u][0]; 
	}
}

int main()
{
	int n;
	while(cin>>n){
		memset(dp,0,sizeof(dp));
		memset(vis,false,sizeof(vis));
		for(int i=1;i<=n;i++){//1~n个人 
			cin>>dp[i][1];
		}
		int u,v;
		while(cin>>u>>v){
			if(u==0&&v==0) break;
			e[v].push_back(u);//v是父亲,u是v的孩子 
			vis[u]=true;//标记,以便找根节点 
		}
		for(int i=1;i<=n;i++){//n个人,从1开始遍历 
			if(!vis[i]){////找根节点若vis[i]==false,则i是根节点 
				dfs(i);
				cout<<max(dp[i][1],dp[i][0])<<endl;
				break;
			}
		} 
		for(int i=1;i<=n;i++) e[i].clear();//清空 
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_41555192/article/details/81570385