Ağacın boyanmasına zirvəsindən başlayırıq. Onu rənglə boyamaq olar.
Tutaq ki, biz zirvəsində yerləşirik. Əgər onun atası yoxdursa (v = 1), onda oğlanları k - 1 rənglə boyamaq olar. Əgər zirvəsinin atası varsa, onda onun oğlanları k - 2 rənglə boyanmalıdır. Çünki zirvəsinin oğlanları arasındakı məsafə -yə bərabərdir, onları eyni rənglərlə boyamaq olmaz.
Tutaq ki, müəyyənlik üçün zirvəsinin atası var. Onda zirvəsinin ilk oğlanını k - 2 rənglə, ikinci oğlanını k - 3 rənglə və s. boyamaq olar.
Hər zirvənin hansı rənglərlə boyanabileceyi hesablanmış rəng saylarını vurmaq qalır.
Nümunə
Birinci nümunə üçün boyama üsulu vardır:
İkinci testə nəzər salaq. Hər zirvənin yanında rəng sayı göstərək. Məsələn, zirvəsini 2 rənglə boyamaq olar, çünki onun rəngi və zirvələrinin rənglərinə uyğun olmamalıdır. Ağacı boyamağın ümumi üsulları 4 \cdot 3 \cdot 2 \cdot 1 \cdot 2 = 48-ə bərabərdir.
Alqoritmin realizasiyası
Girişdə verilən qraf qonşuluq siyahısında saxlanılır. sabiti – modulunu elan edirik.
#define MOD 1000000007
vector<vector<int>> g;dfs funksiyası kökə zirvəsindən başlanan ağacın boyanma üsullarının sayını MOD = 10^9 + 7 modulu üzrə qaytarır. zirvəsinin atası -dir. zirvəsi rənglərlə boyana bilər.
int dfs(int v, int col, int p = -1)
{
long long res = col;Biz zirvəsində yerləşirik. zirvəsinin oğlanlarının hansı rənglərlə boyanmayacağını dəyişənində qeyd edirik. Əvvəlcə cnt = 1 qoyuruq, çünki zirvəsinin oğlanları zirvəsinin rəngi ilə eyni ola bilməz. Əgər zirvəsinin atası varsa (p \ne -1), onda zirvəsinin oğlanları -nin atasının rəngi ilə də eyni ola bilməz.
int cnt = 1;
if (p >= 0) cnt++;zirvəsinin to oğlanlarını dolaşırıq.
for (int to : g[v])
if (to != p)
{to zirvəsi k - cnt rənglə boyana bilər. Hər oğlanla cnt dəyəri 1 artır.
res = (res * dfs(to, k - cnt, v)) % MOD;
cnt++;
}
return res;
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyuruq.
scanf("%d %d", &n, &k);
g.resize(n + 1);
for (i = 0; i < n - 1; i++)
{
scanf("%d %d", &a, &b);
g[a].push_back(b);
g[b].push_back(a);
}Dərinlik axtarışını zirvəsindən başlayırıq. zirvəsi rənglə boyana bilər.
res = dfs(1, k);Cavabı ekrana çıxarırıq.
printf("%lld\n", res);Python realizasiyası
Python interpretatorunun maksimum dərinliyini müəyyən edirik.
import sys
sys.setrecursionlimit(1000000)sabitini – modulu elan edirik.
MOD = 1000000007dfs funksiyası kökə zirvəsindən başlanan ağacın boyanma üsullarının sayını MOD = 10^9 + 7 modulu üzrə qaytarır. zirvəsinin atası -dir. zirvəsi rənglərlə boyana bilər.
def dfs(v, col, p = -1):
res = colBiz zirvəsində yerləşirik. zirvəsinin oğlanlarının hansı rənglərlə boyanmayacağını dəyişənində qeyd edirik. Əvvəlcə cnt = 1 qoyuruq, çünki zirvəsinin oğlanları zirvəsinin rəngi ilə eyni ola bilməz. Əgər zirvəsinin atası varsa (p \ne -1), onda zirvəsinin oğlanları -nin atasının rəngi ilə də eyni ola bilməz.
cnt = 1
if p >= 0: cnt += 1zirvəsinin oğlanlarını dolaşırıq.
for to in g[v]:
if to != p:to zirvəsi k - cnt rənglə boyana bilər. Hər oğlanla cnt dəyəri 1 artır.
res = (res * dfs(to, k - cnt, v)) % MOD
cnt += 1
return resProqramın əsas hissəsi. Giriş məlumatlarını oxuyuruq.
n, k = map(int, input().split())
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)Dərinlik axtarışını zirvəsindən başlayırıq. zirvəsi rənglə boyana bilər.
res = dfs(1, k)Cavabı ekrana çıxarırıq.
print(res)