Şirkət strukturu bir ağacdır. Hər bir ağacının zirvəsi üçün onun kök olduğu alt ağacdaki zirvələrin sayını tapmaq lazımdır. O zaman işçisinin altının sayını sum[v] - 1 (çünki işçi öz altı deyil) olaraq tapmaq olar.
Şirkətin baş direktoruna uyğun gələn 1-ci zirvədən danışıqları dərinlikdə ayaqlamağa başlayaq. Əgər to_1, to_2, ..., to_k zirvəsinin oğullarıdırsa, onda:
Əgər zirvəsi ağacın yarpağıdırsa, onda sum[v] = 1 təyin edək.
Misal
Misalı nəzərdən keçirək. Hər bir işçinin (qraf zirvəsi) yanında onun altlarının sayı göstərilir.
Alqoritmin implementasiyası
Ağac qonşuluq siyahısında saxlanılır.
vector<vector<int> > g;dfs funksiyası dinclikdə axtarışı zirvə -dən həyata keçirir və kökü olan alt ağacdakı zirvələrin sayını qaytarır. Zirvə , dinclikdə axtarışda -nin əcdadıdır.
int dfs(int v, int p)
{Kökü olan alt ağac başlanğıcda yalnız bir zirvə - zirvə -ni ehtiva edir.
sum[v] = 1;v → to kənarını nəzərdən keçiririk. Əgər to \ne p, onda -nin üzərinə kökü olan alt ağacdakı zirvələrin sayını əlavə edirik.
for (int to : g[v])
if (to != p) sum[v] += dfs(to, v);Kökü olan alt ağacdakı zirvələrin sayını qaytarırıq.
return sum[v];
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyuruq. Ağacı qururuq.
scanf("%d", &n);
g.resize(n + 1);
for (i = 2; i <= n; i++)
{
scanf("%d", &x);İşçi üçün şirkətdəki birbaşa müdir -dir.
g[i].push_back(x);
g[x].push_back(i);
}1-ci zirvədən danışıqları dərinlikdə ayaqlamağa başlayaq.
sum.resize(n + 1);
dfs(1, -1);Cavabı çıxardırıq. İşçi -nin altlarının sayı -ə bərabərdir.
for (i = 1; i <= n; i++)
printf("%d ", sum[i] - 1);
printf("\n");Java implementasiyası
import java.util.*;
public class Main
{
static ArrayList<Integer>[] g;
static int sum[];
static int n;
static int dfs(int v, int p)
{
sum[v] = 1;
for(int to : g[v])
if (to != p) sum[v] += dfs(to,v);
return sum[v];
}
@SuppressWarnings("unchecked")
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
n = con.nextInt();
g = new ArrayList[n+1]; // unchecked
sum = new int[n+1];
for (int i = 0; i <= n; i++)
g[i] = new ArrayList<Integer>();
for (int i = 2; i <= n; i++)
{
int x = con.nextInt();
g[i].add(x);
g[x].add(i);
}
dfs(1,-1);
for (int i = 1; i <= n; i++)
System.out.print(sum[i] - 1 + " ");
System.out.println();
con.close();
}
} Python implementasiyası
Rekursiya üçün steki artıracağıq.
import sys
sys.setrecursionlimit(1000000)dfs funksiyası zirvə -dən dinclikdə axtarış həyata keçirir və kökü olan alt ağacdakı zirvələrin sayını qaytarır. Zirvə , dinclikdə axtarışda -nin əcdadıdır.
def dfs(v, p):Kökü olan alt ağac başlanğıcda yalnız bir zirvə - zirvə -ni ehtiva edir.
sum[v] = 1v → to kənarını nəzərdən keçiririk. Əgər to \ne p, onda -nin üzərinə kökü olan alt ağacdakı zirvələrin sayını əlavə edirik.
for to in g[v]:
if to != p: sum[v] += dfs(to,v)Kökü olan alt ağacdakı zirvələrin sayını qaytarırıq.
return sum[v]Proqramın əsas hissəsi. İşçilərin sayını oxuyuruq.
n = int(input())Qrafagır orta siyahını inizialize edirik.
g = [[] for _ in range(n+1)]Giriş məlumatlarını oxuyuruq. Ağacı qururuq.
lst = list(map(int, input().split()))
for i in range(2,n+1):
a = lst[i-2]İşçi i~(i \ge 2) üçün birbaşa müdir şirkətdə -dır.
g[a].append(i)
g[i].append(a)siyahısını inizialize edirik.
sum = [0] * (n + 1)1-ci zirvədən danışıqları dərinlikdə ayaqlamağa başlayaq.
dfs(1,-1)Cavabı çıxardırıq. İşçi -nin altlarının sayı sum[i] - 1-ə bərabərdir.
for i in range(1, n+1):
print(sum[i] - 1,end=" ")