Kəfa'nın evi olan təpəsindən dərinlik üzrə axtarışa başlaq. dfs funksiyasının parametrlərindən birində ardıcıl gələn pişiklərlə təpələrin sayını saxlayacağıq. Əgər təpəsində bu sayı -i keçərsə, bu təpədən dərinlik üzrə axtarışı davam etdirmirik. Ziyarət edilən yarpaqların sayını hesablayırıq. Bir təpə yarpaqdır ki, onun dərəcəsi -ə bərabərdir və özü kök deyil (yəni təpəsi deyil).
Misal
Birinci və ikinci misallardakı ağacları nəzərdən keçirək.
Birinci misalda Kəfa yalnız bir pişiklə olan təpədən ardıcıl keçə bilər. O, və təpələrində yerləşən restoranlara çatacaq.
İkinci misalda Kəfa yalnız iki pişiklə olan təpələrdən ardıcıl keçə bilər. O, və təpələrində yerləşən restoranlara çatacaq.
Alqoritmin reallaşdırılması
Pişiklərin yerləşməsini massivində saxlayırıq. Ağacı qarşılıqlı əlaqə siyahısında saxlayırıq.
vector<int> cats;
vector<vector<int> > g;dfs funksiyası təpəsindən dərinlik üzrə axtarış yerinə yetirir və bu təpədən hansı restoranlara gedilə biləcəyini qaytarır (şərt o ki, bu yolda -dən çox ardıcıl pişiklə təpələr olmasın). təpəsinin atası təpəsidir. təpəsinə qədər keçilmiş ardıcıl pişiklərlə təpələrin sayı -yə bərabərdir.
int dfs(int v, int prev, int cnt)
{Əgər artıq ardıcıl -dən çox pişiklə keçilibsə, təpəsindən dərinlik üzrə axtarış davam olunmur.
if (cnt > m) return 0;Əgər yarpaqdayıqsa, bilinən restoranların sayını artırırıq.
if (g[v].size() == 1 && prev != -1) return 1;Promennaya , təpəsindən mümkün olan restoranların sayını hesablayır.
int res = 0;təpəsindən çıxan bütün kənarları (v, to) keçiririk. Əgər təpəsi üçün atadırsa, bu təpəyə keçid etmə.
for (int to : g[v])
if (to != prev)
{Əgər təpəsində pişik yoxdursa, c = 0 təyin edirik. Əks halda c = cnt + 1. Promennaya təpəsinə qədər pişiklə olan ardıcıl təpələrin sayını saxlayır.
int c = (cats[to] == 0) ? 0 : cnt + 1;təpəsindən dərinlik üzrə axtarışa başlayırıq.
res += dfs(to, v, c);
}Nəticəni qaytarırıq.
return res;
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyarıq.
scanf("%d %d", &n, &m);
cats.resize(n + 1);
for (i = 1; i <= n; i++)
scanf("%d", &cats[i]);Ağacı qururuq.
g.resize(n + 1);
for (i = 1; i < n; i++)
{
scanf("%d %d", &a, &b);
g[a].push_back(b);
g[b].push_back(a);
}Cavabı çıxışa veririk. təpəsindən çağırılan dfs funksiyası məsələyə cavab verir. təpəsinin atası olmadığı üçün ikinci parametrin qiyməti olur. təpəsindən başlayaraq biz pişikləri ziyarət etdik.
printf("%d\n", dfs(1, -1, cats[1]));Python realizasiyası
dfs funksiyası təpəsindən dərinlik üzrə axtarış yerinə yetirir və bu təpədən hansı restoranlara gedilə biləcəyini qaytarır (şərt o ki, bu yolda -dən çox ardıcıl pişiklə təpələr olmasın). təpəsinin atası təpəsidir. təpəsinə qədər keçilmiş ardıcıl pişiklərlə təpələrin sayı -yə bərabərdir.
def dfs(v, prev, cnt):Əgər artıq ardıcıl -dən çox pişiklə keçilibsə, təpəsindən dərinlik üzrə axtarış davam olunmur.
if cnt > m:
return 0Əgər yarpaqdayıqsa, bilinən restoranların sayını artırırıq.
if len(g[v]) == 1 and prev != -1:
return 1Promennaya , təpəsindən mümkün olan restoranların sayını hesablayır.
res = 0təpəsindən çıxan bütün kənarları (v, to) keçiririk. Əgər təpəsi üçün atadırsa, bu təpəyə keçid etmə.
for to in g[v]:
if to != prev:Əgər təpəsində pişik yoxdursa, c = 0 təyin edirik. Əks halda c = cnt + 1. Promennaya təpəsinə qədər pişiklə olan ardıcıl təpələrin sayını saxlayır.
c = 0 if cats[to] == 0 else cnt + 1təpəsindən dərinlik üzrə axtarışa başlayırıq.
res += dfs(to, v, c)Nəticəni qaytarırıq.
return resProqramın əsas hissəsi. Giriş məlumatlarını oxuyarıq.
n, m = map(int, input().split())
cats = [0] + list(map(int, input().split()))Ağacı qururuq.
g = [[] for _ in range(n + 1)]
for _ in range(n - 1):
a, b = map(int, input().split())
g[a].append(b)
g[b].append(a)Cavabı çıxışa veririk. təpəsindən çağırılan dfs funksiyası məsələyə cavab verir. təpəsinin atası olmadığı üçün ikinci parametrin qiyməti olur. təpəsindən başlayaraq biz pişikləri ziyarət etdik.
print(dfs(1, -1, cats[1]))