--- tags: CSES題解 --- CSES Problem Set — Subordinates 題解 === 題目 --- 給一個公司的結構,計算每個員工有幾個下屬 ### 輸入 第一行有一個整數 $n$ : 代表員工的數量。員工的編號為 $1,2,\dots,n$ 且一號員工是公司的最高負責人 之後,有 $n-1$ 個整數: 代表$2,3,\dots,n$ 編號員工的上司 ### 輸出 輸出 $n$ 個整數 : 對每個員工編號為 $1,2,\dots,n$ 的下屬數量 想法 --- 透過``DFS``走訪整棵樹,遞迴子樹結束後再加上子樹的大小。 由於樹的特殊性質,子樹只能透過父節點走到子樹以外的部分,只要``DFS``時特判父節點就不需要``visit``陣列來維護有沒有走訪過。 範例程式碼 --- ```cpp= #include<bits/stdc++.h> #define int long long using namespace std; int cnt=1; vector<int> Head(200500,0); vector<int> Next(400500); //邊數量記得開兩倍 vector<int> To(400500); //因為正反都要建 vector<int> Size(200500); void addEdge(int u,int v){ Next[cnt]=Head[u]; To[cnt]=v; Head[u]=cnt++; } /*************鍊式前向星建圖****************/ void dfs(int u,int par){ Size[u]=0; for(int e=Head[u];e;e=Next[e]){ int v=To[e]; if(v!=par){ dfs(v,u); Size[u]+=Size[v]+1; //遞迴完子樹加上子樹大小 } } } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); int n; cin>>n; for(int i=2;i<=n;i++){ int t; cin>>t; addEdge(i,t); addEdge(t,i); } dfs(1,1); for(int i=1;i<=n;i++) cout<<Size[i]<<" \n"[i==n]; return 0; }