P1122 最大子樹和(樹形動態規劃)

2021-08-21 19:33:49 字數 1777 閱讀 6947

題幹在這裡:

本題老師教了我兩種方法,和大家分享一下,希望能幫到大家~~~

第一種思路:

由於每兩個點之間都有一些聯絡,我們可以先把兩兩之間的關係用邊的形式儲存下來:

head[x]是表示與x相連的第乙個元素的下標

edge[x].po是表示鏈頭為x

edge[x].next是表述鏈頭是x,與x相連的元素的下標

運作方法:每讀入乙個數k,就將head[x]轉變為k,之後再由edge陣列轉變下去,這樣就將k與整個鏈連線起來了

動態規劃總是要有狀態轉移方程的,我們用f[x]表示以x為根的最大價值數(其實就是題目中所謂的美麗指數,只不過這個名字太奇怪了。。。)。用g[x]表示以x為根,並且一定要取x的最大價值數

先考慮g[x]的狀態轉移方程:

考慮f[x]是否取x:

如果不取,那麼和他相連的子樹都可以取,狀態轉移方程是(其中y具體取值請參看本人的**):

當x是根的時候,需要用到它的子樹列,用深搜就可以實現。深搜有兩個引數:x表示處理的物件,fa表示該物件的父親(之後是不能再回到fa的!!)

最後獻上**~~~

#include

const

int maxn=20000;

const

int minvalue=-2147483647;

using

namespace

std;

struct node edge[2*maxn];

int head[maxn],n,a,b,value[maxn],tot,f[maxn],g[maxn];

void insert(int x,int y)

void readin()

for(int i=1;icin>>a>>b;

insert(a,b);

insert(b,a);

}} void dfs(int x,int fa)

t=edge[t].next;

}f[x]=max(f[x],g[x]);

} int main()

第二種思路:

儲存兩數關係方法與第一種思路一樣,連狀態轉移方程都一樣,就是求最大價值數的方法不同,上面了深搜的方法,將我們需要的狀態在需要的時候求出來。

這次的思路是:直接將所有的狀態都求出來,再從後往前改變每個父節點的最大價值數,這個可以用寬搜來實現。

最後附上我的**~~~

#include

#include

using

namespace

std;

const

int minvalue=-2147483647;

const

int maxn=200000;

struct nodetree[2*maxn];

int n,head[maxn],a,b,tot,qwq=1;

int value[maxn],f[maxn][2],g[maxn],k[maxn];

bool panduan[maxn];

void insert(int x,int y)

void readin()

for(int i=1;icin>>a>>b;

insert(a,b);

insert(b,a);

}}void bfs()

t=tree[t].next;

}st++;

}}void work()

}int main()

P1122 最大子樹和 (樹形DP)

第一次寫樹形dp,找了乙個簡單的題,先熟悉一下套路,雖然自己的這種寫法,過了,可以求到最大的子樹和,但是不能求到每個結點的最大子樹和,只有某一部分的最大子樹和的根,它是正確的,其他結點都是打工仔。遞迴下去,以子樹推當前結點和子樹的最優值,是可以辦到的 情況1 如果當前子樹 0,就不更新 情況2 如果...

P1122 最大子樹和

小明對數學飽有興趣,並且是個勤奮好學的學生,總是在課後留在教室向老師請教一些問題。一天他早晨騎車去上課,路上見到乙個老伯正在修剪花花草草,頓時想到了乙個有關修剪花卉的問題。於是當日課後,小明就向老師提出了這個問題 一株奇怪的花卉,上面共連有nn朵花,共有n 1n 1條枝幹將花兒連在一起,並且未修剪時...

P1122 最大子樹和 題解

同步 原題鏈結 簡要題意 給定一棵 n nn 個節點的樹,有點權,求其中最大的連通塊之和。資料範圍 n 1.6 1 04 n leq 1.6 times 10 4 n 1.6 104.很顯然,考慮用樹形 dp text dp 解決此題。f uf u fu 表示以 u uu 為根的子樹中包含 u uu...