題目鏈結題意:給你一棵樹,按順序輸出以每個頂點為根節點,到任意點的邊權和最大,輸出這個最大值。
思路:換根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為根的結果能否快速求出以它某兒...