每日一題 4月8日題目精講 黑白樹

2022-05-05 14:39:09 字數 1395 閱讀 3185

試題鏈結

時間限制:c/c++ 1秒,其他語言2秒 空間限制:c/c++ 32768k,其他語言65536k 64bit io format:%lld

題目描述

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

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

輸入描述:

第一行乙個整數n (1 ≤ n ≤ 105) 接下來n-1行,每行乙個整數,依次為2號點到n號點父親的編號。 最後一行n個整數為k[i]

(1 ≤ k[i] ≤ 105)

樣例解釋:

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

輸出描述:

乙個數表示最少操作次數

示例1輸入

412

1122

1

輸出

3
題解:

一開始以為是紅黑樹的姐妹黑白樹。。

求出最少的操作,用dfs

我們要不斷更新染色的最遠距離,還要把子節點的染色範圍更新的父親節點

比如1->2->3-.>4->5->6->7

f[2]=5,f[3]=2

2節點就可以直接染色到6

操作完2之後,如果3就已經被染色了,如果3能染色的範圍比fa[ 2 ]-1(因為2已經染色了本身,所以減一)還大,那染色範圍可以更遠

如果fa[3]因為染色都是從下向上的。如果乙個節點沒辦法被它子樹的節點染色,那這個節點的父親節點也沒辦法將它染色,他只能自己染色了

**:

#include

#define forr(n) for(int i=1;i<=n;i++)

using

namespace std;

const

int maxn=

100004

;int fa[maxn]

;int sum;

vector<

int>w[maxn]

;int a[maxn]

;void

dfs(

int x)

if(fa[x]==0

)}intmain()

forr

(n)dfs(1

);cout

}

每日一題 4月7日題目精講 樹

樹 時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k 其他語言262144k 64bit io format lld 題目描述 shy有一顆樹,樹有n個結點。有k種不同顏色的染料給樹染色。乙個染色方案是合法的,當且僅當對於所有相同顏色的點對 x,y x到y的路徑上的所有點的顏色...

每日一題 8月7日題目精講 雙棧排序

時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k,其他語言262144k 64bit io format lld tom最近在研究乙個有趣的排序問題。如圖所示,通過2個棧s1和s2,tom希望借助以下4種操作實現將輸入序列公升序排序。操作a 如果輸入序列不為空,將第乙個元素壓入...

每日一題 8月11日題目精講 矩陣消除遊戲

首先,我們很容易得到,先選哪一行 列 後選哪一行 列 只要選的一樣是不影響結果的,這個我相信大家都能看出來啦 第二,如果只按行選,或者只按列選,貪心妥妥的 把合最大的幾行加起來就ok啦 第三,也是本題第乙個問題 如果只按列選或者只按行選沒有交叉就一定是最大值嗎?沒有交叉只能保證選的數字最多,但是未必...