試題鏈結
時間限制: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啦 第三,也是本題第乙個問題 如果只按列選或者只按行選沒有交叉就一定是最大值嗎?沒有交叉只能保證選的數字最多,但是未必...