列表

详情


NC50513. 周年纪念晚会

描述

Ural州立大学的校长正在筹备学校的80周年纪念聚会。由于学校的职员有不同的职务级别,可以构成一棵以校长为根的人事关系树。每个资源都有一个唯一的整数编号,从1到N编号,且对应一个参加聚会所获得的欢乐度。为使每个职员都感到快乐,校长设法使每个职员和其直接上司不会同时参加聚会。
你的任务是设计一份参加聚会者的名单,使总欢乐度最高。

输入描述

第一行是一个整数N;
接下来N行对应N个职员的欢乐度,第i行的一个整数为第i个职员的欢乐度p_i
接着是学校的人事关系树,每一行格式为LK,表示第K个职员是第L个职员的直接上司,输入以00结束。

输出描述

输出参加聚会者获得的最大欢乐度。

示例1

输入:

7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0

输出:

5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 7ms, 内存消耗: 1396K, 提交时间: 2019-10-26 22:05:31

#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio> 
#define maxn 10000
using namespace std;
vector<int>G[maxn];
int list[maxn];
void insert(int be,int en){
	G[be].push_back(en);
}
int n,m;
int vis[maxn];
int f[maxn];
int g[maxn];
int dfs(int x,int fa){
	vis[x] =1;
	int a = 0;
	int b = 0;
	for(int i=0;i<G[x].size();i++){
		int p = G[x][i];
		if(p == fa) continue;
		dfs(p,x);
		f[x] += max(f[p],g[p]);
		g[x] += f[p];
	}
	
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&list[i]);
		g[i] = list[i];
	}
	int be,en;
	for(int i=0;i<n;i++){
		scanf("%d %d",&be,&en);
		if(be == en && en == 0) continue;
		insert(be,en);
		insert(en,be);
	}
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			dfs(i,-1);
			printf("%d\n",max(g[i],f[i]));
		}	
	}
	
	return 0;
} 







C++ 解法, 执行用时: 37ms, 内存消耗: 32144K, 提交时间: 2022-06-21 21:21:09

#include<bits/stdc++.h>
using namespace std;
int n;
struct node
{
	int x,isroot;
	vector<int> son;
}s[1000001];
int f[1000001][2];
void dfs(int x)
{
	f[x][0]=0;
	f[x][1]=s[x].x;
	for (int i=0;i<s[x].son.size();i++){
		dfs(s[x].son[i]);
		f[x][0]+=max(f[s[x].son[i]][0],f[s[x].son[i]][1]);
		f[x][1]+=f[s[x].son[i]][0];
	}
}
int main(){
	cin>>n;
	for (int i=1;i<=n;i++){
		cin>>s[i].x;
		s[i].isroot=1;
	}
	while(1){
		int x,y;
		cin>>x>>y;
		if(x==0&&y==x)break;
		s[y].son.push_back(x);
		s[x].isroot=0;
	}
	for (int i=1;i<=n;i++){
		if (s[i].isroot){
			dfs(i);
			cout<<max(f[i][0],f[i][1]);
			return 0;
		}
	}
}

上一题