143. Long Live the Queen
time limit per test: 0.25 sec.
memory limit per test: 4096 KB
The Queen of Byteland is very loved by her people. In order to show her their love, the Bytelanders have decided to conquer a new country which will be named according to the queen‘s name. This new country contains N towns.
The towns are connected by bidirectional roads and there is exactly ONE path between any two towns, walking on the country‘s roads. For each town, the profit it brings to the owner is known. Although the Bytelanders love their queen very much,
they don‘t want to conquer all the N towns for her. They will be satisfied with a non-empty subset of these towns, with the following 2 properties: there exists a path from every town in the subset to every other town in the
subset walking only through towns in the subset and the profit of the subset is maximum. The profit of a subset of the N towns is equal to the sum of the profits of the towns which belong to the subset. Your task is to find the maximum profit
the Bytelanders may get.
Input
The first line of input will contain the number of towns N (1<=N<=16 000). The second line will contain N integers: the profits for each town, from 1 to N.
Each profit is an integer number between-1000 and 1000. The next N-1 lines describe the roads: each line contains 2 integer numbers a and b, separated by
blanks, denoting two different towns between which there exists a road.
Output
The output should contain one integer number: the maximum profit the Bytelanders may get.
Sample Input
5 -1 1 3 1 -1 4 1 1 3 1 2 4 5
Sample Output
4
题意 :给定一棵树,每个节点上权值为整数。求它的一个连通子图,使其所有节点权值之和最大。
思路 :dp[ i ] 表示以编号 i 的节点为根的字数中,在选 i 这个点的前提下,可以选择的最大子树的权值和。
即 dp [ i ] += max(0,dp[ v ] ) v 为节点 i的儿子节点。
#include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; const int inf=999999999; const int maxn=16010; int dp[maxn],a[maxn],n,root; vector <int> G[maxn]; void input() { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&a[i]); int u,v; for(int i=1; i<n; i++) { scanf("%d %d",&u,&v); G[u].push_back(v); G[v].push_back(u); } } void dfs(int u,int v) { for(int i=0; i<G[v].size(); i++) { int vv=G[v][i]; if(vv!=u) dfs(v,vv); } for(int i=0; i<G[v].size(); i++) { int vv=G[v][i]; if(vv!=u) dp[v]+=max(0,dp[vv]); } } void solve() { for(int i=1; i<=n; i++) dp[i]=a[i]; dfs(-1,1); int ans=-inf; for(int i=1; i<=n; i++) ans=max(ans,dp[i]); printf("%d\n",ans); } int main() { input(); solve(); return 0; }