Почнемо розфарбовку дерева з вершини . Її можна пофарбувати кольорами.
Нехай ми знаходимося у вершині . Якщо вона не має предка (v = 1), то синів можна розфарбувати k - 1 кольорами. Якщо вершина має предка, то її синів можна пофарбувати k - 2 кольорами. Оскільки відстань між синами вершини дорівнює , то їх не можна фарбувати однаковими кольорами.
Нехай для визначеності вершина має предка. Тоді першого сина можна пофарбувати k - 2 кольорами, другого сина k - 3 кольорами і так далі.
Залишається перемножити кількості кольорів, якими можна розфарбувати кожну вершину.
Приклад
Для першого прикладу маємо способів розфарбування:
Розглянемо другий тест. Біля кожної вершини вкажемо кількість кольорів, якими її можна пофарбувати. Наприклад, вершину можна пофарбувати 2 кольорами, оскільки її колір не повинен збігатися з кольорами вершин і . Загальна кількість способів пофарбувати дерево дорівнює 4 \cdot 3 \cdot 2 \cdot 1 \cdot 2 = 48.
Реалізація алгоритму
Вхідний граф зберігаємо в списку суміжності . Оголосимо константу — модуль .
#define MOD 1000000007
vector<vector<int>> g;Функція dfs повертає кількість способів розфарбувати дерево з коренем у вершині за модулем MOD = 10^9 + 7. Предком вершини є . Вершину можна пофарбувати кольорами.
int dfs(int v, int col, int p = -1)
{
long long res = col;Ми знаходимося у вершині . У змінній відзначаємо кількість кольорів, якими не можна фарбувати синів вершини . Спочатку встановимо cnt = 1, оскільки сини вершини не можуть мати колір вершини . Якщо вершина має предка (p \ne -1), то сини вершини також не можуть мати колір предка .
int cnt = 1;
if (p >= 0) cnt++;Перебираємо синів to вершини .
for (int to : g[v])
if (to != p)
{Вершина може бути пофарбована k - cnt кольорами. З кожним сином значення буде збільшуватись на .
res = (res * dfs(to, k - cnt, v)) % MOD;
cnt++;
}
return res;
}Основна частина програми. Читаємо вхідні дані.
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);
}Запускаємо пошук у глибину з вершини . Вершину номер можна пофарбувати кольорами.
res = dfs(1, k);Виводимо відповідь.
printf("%lld\n", res);Python реалізація
Встановимо максимальну глибину стека інтерпретатора Python.
import sys
sys.setrecursionlimit(1000000)Оголосимо константу — модуль .
MOD = 1000000007Функція dfs повертає кількість способів розфарбувати дерево з коренем у вершині за модулем MOD = 10^9 + 7. Предком вершини є . Вершину можна пофарбувати кольорами.
def dfs(v, col, p = -1):
res = colМи знаходимося у вершині . У змінній відзначаємо кількість кольорів, якими не можна фарбувати синів вершини . Спочатку встановимо cnt = 1, оскільки сини вершини не можуть мати колір вершини . Якщо вершина має предка (p \ne -1), тоді сини вершини також не можуть мати колір предка .
cnt = 1
if p >= 0: cnt += 1Перебираємо синів вершини .
for to in g[v]:
if to != p:Вершина може бути пофарбована k - cnt кольорами. З кожним сином значення буде збільшуватись на .
res = (res * dfs(to, k - cnt, v)) % MOD
cnt += 1
return resОсновна частина програми. Читаємо вхідні дані.
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)Запускаємо пошук у глибину з вершини . Вершину номер можна пофарбувати кольорами.
res = dfs(1, k)Виводимо відповідь.
print(res)