Nowcoder 黑白樹 樹形dp

2021-10-03 13:31:34 字數 2231 閱讀 5922

一棵n個點的有根樹,1號點為根,相鄰的兩個節點之間的距離為1。樹上每個節點i對應乙個值k[i]。每個點都有乙個顏色,初始的時候所有點都是白色的。

你需要通過一系列操作使得最終每個點變成黑色。每次操作需要選擇乙個節點i,i必須是白色的,然後i到根的鏈上(包括節點i與根)所有與節點i距離小於k[i]的點都會變黑,已經是黑的點保持為黑。問最少使用幾次操作能把整棵樹變黑。

第一行乙個整數n (1 ≤ n ≤ 10^5)

接下來n-1行,每行乙個整數,依次為2號點到n號點父親的編號。

最後一行n個整數為k[i] (1 ≤ k[i] ≤ 10^5)

樣例解釋:

對節點3操作,導致節點2與節點3變黑

對節點4操作,導致節點4變黑

對節點1操作,導致節點1變黑

乙個數表示最少操作次數
題目思路:

話說這是美團初賽?

解決這道題,看到網上的說法 層出不窮 但都沒有怎麼好好解釋這一道題目,今天來解釋一下這道好題:

1.要想解決這個問題 首先要解決基礎版本,把這個問題放到 x軸上:起初所有點都是白色,每次對乙個白色的點進行操作,每次操作會將包括該點及以後的k[i]個點染黑,問最少染色次數。

可能開始思路貪心都差不多,從左到右一直染色,直到不能再染,再開一種新的顏色。

這種思路很明顯對於上面紅色的例子就不對,正確結果應該是2,貪心思路得到為4

原因在於:2可以染色到第三個點,但是第三個點如果被第二個點5染色的話 結果會更優——因為5不僅可以染3還可以染4 5

所以說,當1第乙個點染到不能再染的時候,應該讓看一看如果然之前的某個點會不會有更長的距離。

所以我們需要記錄一下之前哪個點染到當前這個點能染的距離更長,那就染那個點來代替這個點。

所以偽**也給出:

int ans=0,res=0;/// res 統計結果 ans 標記之前的點到該點後能夠往後延伸的最大距離

for(int i=1;i<=n;i++)

else dp[i+1]=dp[i]-1;///正常遞推

ans=max(num[i],ans);///過程中記錄

ans--;///下乙個點ans就要--

}

有人會質疑之前的染過一次的點會不會染第二次答案是不可能的..(因為如果當前!dp[i],說明染過的點剛好到當前點之後為0,那麼最少最少num[i]>=1)

2.現在把問題高階一下,放到樹上:

其實放到樹上的思路是一模一樣的,dp[i+1]變為 當前節點i的父節點就可以了。

我們判斷當前dp[u]還可不可以染色,直接用dfs返回子樹中到達當前還可以染色的最大距離,每次dp[u]不能染色的時候,答案就要++,將dp[u]更新成最大染色距離,再繼續使其染色。

具體**:

/*** keep hungry and calm coolguang!***/

#pragma gcc optimize(2)

#include #define debug(x) cout<<#x<<":"<'9')) in=getchar();if(in=='-')else num=in-'0';while(in=getchar(),in>='0'&&in<='9')if(isn) num=-num;return true;}

ll n,m,p;

vectorg[maxn];

int num[maxn];

int dp[maxn];///未使用過的保留的最大值

int res=0;

int dfs(int u,int fa)

if(dp[u]==0)

dp[fa]=max(dp[fa],dp[u]-1);///更新一下父節點

return ans-1;

}int main()

for(int i=1;i<=n;i++) scanf("%d",&num[i]);

dfs(1,1);

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

return 0;

}/**

7 2 1

2 53 7

**/

這題**還是比較短,比較側重於思維和dp的推法,想了一天,不過做出來也算有所收穫。

精髓在於 每個點維護的不是答案值了 而是從當前點出發還能染色的最大距離,如果當前點被之前的點染不到了,那麼該點就要從該點出發重新染色,染色的話選擇能染的最多的距離,就可以保證最優。

Nowcoder13249 黑白樹(樹形DP)

一棵n個點的有根樹,1號點為根,相鄰的兩個節點之間的距離為1。樹上每個節點i對應乙個值k i 每個點都有乙個顏色,初始的時候所有點都是白色的。你需要通過一系列操作使得最終每個點變成黑色。每次操作需要選擇乙個節點i,i必須是白色的,然後i到根的鏈上 包括節點i與根 所有與節點i距離小於k i 的點都會...

黑白樹(牛客網 樹形dp)

題目描述 一棵n個點的有根樹,1號點為根,相鄰的兩個節點之間的距離為1。樹上每個節點i對應乙個值k i 每個點都有乙個顏色,初始的時候所有點都是白色的。你需要通過一系列操作使得最終每個點變成黑色。每次操作需要選擇乙個節點i,i必須是白色的,然後i到根的鏈上 包括節點i與根 所有與節點i距離小於k i...

牛客網 黑白樹(樹形dp)

一棵n個點的有根樹,1號點為根,相鄰的兩個節點之間的距離為1。樹上每個節點i對應乙個值k i 每個點都有乙個顏色,初始的時候所有點都是白色的。你需要通過一系列操作使得最終每個點變成黑色。每次操作需要選擇乙個節點i,i必須是白色的,然後i到根的鏈上 包括節點i與根 所有與節點i距離小於k i 的點都會...