【洛谷】P1122 最大子樹和
0.總結
Get to the points firstly, the article comes from LawsonAbs!
- 樹型dp
1.題意
這應該是經典的一道dp題。 言下之意就是要非常熟悉。
- 抽象看題目:給出一棵樹結構,每個節點都有一個權重值,如何選取一個連通塊使得其節點權值和最大?
2.分析
- 認真思考能不能把一個樹相關問題用遞歸的方法解決
3.代碼
// Created by lawson on 20-6-19.
#include<iostream>
#include<cmath>
using namespace std;
const int maxN = 16005;
int n,ans = 0 ;
int beau[maxN];//美麗指數
int dp[maxN];//dp[i]表示以i爲根且包含i可得的最大權聯通塊
int head[maxN],nex[maxN],to[maxN];//
int tot = 1;//辺的個數
//建數組鄰接表
void add(int a,int b ){
nex[tot] = head[a];//更新上一條辺的序號
head[a] = tot; //結點a的第一條辺是head[a]
to[tot] = b;//第tot條辺的終點
tot++;
}
//深搜找辺 => cur 表示當前的頂點,fa 表示是頂點cur的父節點
void dfs(int cur,int fa){
dp[cur] = beau[cur];
for(int i = head[cur];i;i=nex[i]){ //遞歸找辺
int y = to[i];//這條邊所在的頂點
//if(y!=cur){ //如果不是當前頂點 => 無環可以直接搞完
if(y!=fa){//從哪個父節點過來,就不能再回去了
dfs(y,cur);
dp[cur] += max(dp[y],0); //取較大值
}
}
ans = max(ans,dp[cur]);
}
int main(){
cin >> n ;
int a,b;
for(int i = 1; i <= n;i++){
cin >> beau[i]; //輸入花的美麗指數
}
//更新一下
for(int i = 1;i<n;i++){
cin >> a >> b;
add(a,b);//建雙向邊
add(b,a);
}
dfs(1,0);
cout << ans <<"\n";
}