換根dp題集

2021-09-29 11:29:52 字數 1580 閱讀 3489

題目鏈結

題意:給你一棵樹,按順序輸出以每個頂點為根節點,到任意點的邊權和最大,輸出這個最大值。

思路:換根dp,兩遍dfs,第乙個dfs求出以這個點為根節點,子樹的最大邊權值,儲存在d陣列中。第二個dfs1,首先算出以u節點為根節點的dp值,儲存在ans陣列裡,然後求出u節點的兒子的字首dp值儲存在suf陣列中,再求出u節點兒子的字尾dp值儲存在x中,那麼換根後的u節點的dp值,d【u】=max(suf【u】【i】,x)。

#include#define pi pairusing namespace std;

#define mk make_pair

#define ll long long

const int maxn=10010;

vectorg[maxn];

vectorsuf[maxn];

ll ans[maxn];

ll d[maxn];

void dfs(int u,int fa)

}void dfs1(int u,int fa)

ans[u]=d[u];

long long x=0;

for(int i=g[u].size()-1;i>=0;i--)

}int main()

dfs(1,0);

dfs1(1,0);

for(int i=1;i<=n;i++)cout《題目鏈結

題意:給你一棵樹,有m個特殊點,問是否存在乙個點,所有的特殊點到這和點的距離都相等。

思路:換根dp,首先我們設兩個陣列mx【maxn】,和mi【maxn】,分別代表離u節點的最遠的特殊點和最近的特殊點,那麼,如果存在乙個點,他的mx【u】等於mi【u】,它即為答案。兩次dfs,第一次求出以u為根節點,子樹特殊點最遠的點和最近的點,第二次dfs1算答案換根。

#includeusing namespace std;

#define pi pair#define mk make_pair

const int maxn=2e5+100;

vectorg[maxn];

vectorpre[maxn];

const int inf=1e9;

int p[maxn],mx[maxn],mi[maxn],flag=0;

void dfs(int u,int fa)

}void dfs1(int u,int fa)

if(mx[u]==mi[u])

int lax=-inf,lai=inf;

for(int i=g[u].size()-1;i>=0;i--)

}int main()

d[maxn];

vectors[maxn];

vectorg[maxn];

bool cmp(int a,int b)

node t=node;

for(int i=g[u].size()-1;i>=0;i--)

}int main()

dfs(1,0);

dfs1(1,0);

printf("%d\n",ans);

}

樹形 dp 換根 dp

樹形dp 樹形動歸一般是依賴於dfs的,根據動歸的後效性,父節點的狀態一般都依賴子節點的狀態以某種方式轉移而來 換根的p2015 設f i j 表示i的子樹上保留j條邊最多蘋果數 p2279 狀態表示f x 0 覆蓋到x的爺爺和x整棵子樹 向上2層 最少個數 f x 1 覆蓋到x的父親和x子樹 向上...

樹形DP 換根DP

某些樹形dp問題中,我們要求的值是類似 以當前節點為根節點得到的答案 卻沒有給出固定的根節點,若仍然按照常規的樹形dp思路對每個點進行dp,我們對每乙個節點均進行一次 dfs 最後的複雜度是 o left n 2 right 如果我們先假設任意乙個點為根進行 dp,求出當前樹形結構下以每個點為根的子...

換根dp入門

本題是要你任選乙個點為根使得樹上的所有點深度之和最小。本題是要你任選乙個點為根使得樹上的所有點深度之和最小。首先考慮如果是指定根節點你會不會做 已知根節點的話,我們只需要一遍dfs 或者bfs 就可以求出每個點的深度,然後求和就可以了。然後我們考慮如果我們知道當前節點x為根的結果能否快速求出以它某兒...