CodeForces - 1324F Maximum White Subtree(树形dp)
題目鏈接:點擊查看
題目大意:給出 n 個點組成的樹,每個點都有一個顏色,非黑即白,現在問對于每個點而言,選出一個連通塊,使得白色點的個數與黑色點的個數做差最大
題目分析:記錄一下div3的第一次ak,實際上應該是偽ak,感謝zx學長最后抬了我一手F題,dp真的是天克我,不過通過這個題真的學到了不少
首先這個題,題意給出的subtree一定別想當然以為是子樹,我一開始就是因為這里讀錯題然后就被卡懵了,這個題中的subtree其實是子連通塊的意思,知道了子連通塊之后,我們就可以兩次樹形dp來做了,因為我們要使得 cnt_white - cnt_black 盡可能大,那么每個節點如果顏色為白色,其貢獻就是 1 ,否則就是 -1 ,這樣問題就轉換為了兩次 dp 求出最大子連通塊的權值和,一次是自底向上,一次自頂向下,自底向上的話我們可以直接維護dp[ i ],表示以點 i 為根的子樹中的最大連通塊,注意這個子樹是有方向的,這也就意味著我們需要自頂向下再來一次,這一次我們主要是為了處理自底向上過程中無法包含的 fa - u 這條樹鏈所代表的子樹,第二次dfs的時候我們就可以直接維護答案了,這一次我們從上向下走的時候,需要額外維護一個sum變量,用于儲存 fa - u 這條鏈所代表的子樹的貢獻,顯然 sum 最小為 0,代表的意義就是不選 fa - u 這條鏈,此時的答案也就是 ans[ u ] = dp[ u ] + sum 了,現在的問題轉換為了如何向下傳遞 sum ,其實無非只有兩種情況:
為什么要討論ans[ u ]呢,因為ans[ u ]此時已經完成了自底向上+自頂向下的更新了,也就是說ans[ u ]代表的就是包含 u 在內的子連通塊的最大權值了,所以ans[ u ]的正負,就決定著能否對相鄰的子節點做出貢獻了,如果ans[ u ]為正的話,那么減去 dp[ v ] 就是 fa - u 這條鏈代表的子樹的權值了
最后代碼實現起來還是比較好寫的了
代碼:
#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e5+100;int a[N],dp[N],ans[N];vector<int>node[N];void dfs1(int u,int fa)//自底向上 {dp[u]=a[u];for(auto v:node[u]){if(v==fa)continue;dfs1(v,u);dp[u]+=max(dp[v],0);} }void dfs2(int u,int fa,int sum)//自頂向下 {ans[u]=dp[u]+sum;for(auto v:node[u]){if(v==fa)continue;dfs2(v,u,max(0,ans[u]-max(0,dp[v])));} }int main() { #ifndef ONLINE_JUDGE // freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); #endif // ios::sync_with_stdio(false);int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",a+i);if(a[i]==0)a[i]=-1;}for(int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);node[u].push_back(v);node[v].push_back(u);}dfs1(1,-1);dfs2(1,-1,0);for(int i=1;i<=n;i++)printf("%d ",ans[i]);return 0; }?
總結
以上是生活随笔為你收集整理的CodeForces - 1324F Maximum White Subtree(树形dp)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷 - P3391 【模板】文艺平衡树
- 下一篇: HDU - 1890 Robotic S