【洛谷】P1122 最大子樹和

【洛谷】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";
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章