給出一棵節點編號為1~n的有根樹,計算它的所有子樹的大小
輸入格式:第一行為乙個整數n;第二行是n個整數,依次表示編號為1到n的節點的父親編號。特別的,父親編號為0表示這個點是根。
輸出格式:輸出一行,n個整數,依次表示編號為1到n的節點為根的子樹的大小。
題目的特殊性在於樹的構建:第一,這不是二叉樹,而是多叉樹;第二,輸入的是每乙個節點的父親而非孩子。
解決方法在於,為每乙個節點維護乙個孩子鍊錶(儲存孩子節點的編號而非指向孩子的指標),同時為所有節點按照編號建立乙個節點陣列,以便按照編號訪問節點。
在多叉樹建立完畢後,就可以計算每個子樹的大小了,無疑,採用遞迴策略。這裡有乙個小細節,可以用乙個陣列儲存那些已經被計算出的子樹大小,以免遞迴過程中重複計算(當然,這樣會消耗空間,也算是以空間換時間吧)。
#include
#include
#include
int hms[
1000005]=
;struct listnode
;struct list
;void
createlist
(struct list* l)
//build the list
void
insertlist
(struct list* l,
int e)
//空表,在尾節點前插入
這裡構建了佇列資料結構,以及上文提到的用於儲存已經計算出的子樹大小的陣列hms
int
how_many_c
(int c,
struct list* tnodes)
else
childnum++
; hms[c]
= childnum;
return childnum;}}
}
這就是核心函式,遞迴計算子樹大小。
int
main()
int fin;
scanf
("%d"
,&fin);if
(fin)
insertlist(&
(treenodes[fin]
), tnode_num)
;for
(int i =
1; i <= tnode_num; i++
)}
主函式,對於輸入的處理不夠優雅,還請海涵。 樹的子樹大小與深度
51nod 2281 這題用的是並查集的思想,由於給定了父子關係,所以很容易知道建立並查集,最後find每個數,並且find函式找到一次某個節點,就給這個節點計數一次,代表這個節點有這個子節點 include using namespace std int num 1005 pre 1005 voi...
求二叉樹所有左子樹的和
面試的時候的問題,當時腦子可能短路了,有個地方想不通,回來總結的時候發現自己有一點點2,不知道那時那刻面試官的心情是如何的崩潰的 可能是這麼想的,這孩子是不是傻 哈哈,在這裡重新更正下 給你的節點形式 node 乙個二叉樹,求所有左子樹的和。先初始化乙個節點 public class node pu...
求樹的每個子樹的重心
前言 每個子樹的重心 p 的定義 刪去該點p後,以x為根的子樹的所有聯通塊的大小均不超過 siz x 2 根據這個重心的定義可以知道一棵子樹的重心必定在他自己所在的重鏈中.所以每次找到他的重兒子為根的子樹的重心,不符合的話就沿著重鏈往上走直至找到復合要求的重心.模版題 include include...