Покращення доріг#10684

Покращення доріг (Розбір)

Нехай — кількість способів покращити якість доріг для піддерева з коренем у вершині . Позначимо через сина вершини .

Нехай to_1, to_2, ..., to_k — сини . Тоді

f(v) = (f(to_1) + 1) \cdot (f(to_2) + 1) \cdot ... \cdot (f(to_k) + 1)

Якщо — листок (вершина, яка не має синів), то покладемо f(v) = 1.

Приклад

Розглянемо приклади, наведені в умові. Для кожної вершини запишемо значення .

У першому прикладі існує способи покращити якість доріг, при яких на шляху від міста до будь-якого іншого міста є не більше однієї поганої дороги. Погані дороги позначені пунктирними лініями, а хороші — суцільними.

Реалізація алгоритму

Всі обчислення виконуються по модулю MOD = 10^9 + 7.

#define MOD 1000000007

Функція dfs обчислює значення — кількість способів покращити якість доріг для піддерева з коренем у вершині . Предком є вершина .

long long dfs(int v, int p = -1)
{
  long long s = 1;

Якщо to_1, to_2, ..., to_k — сини , то

f(v) = (f(to_1) + 1) \cdot (f(to_2) + 1) \cdot ... \cdot (f(to_k) + 1)
  for (int to : g[v])
    if (to != p)
    {
      long long sub = dfs(to, v);
      s = (s * (sub + 1)) % MOD;
    }
  return s;
}

Читаємо вхідні дані. Будуємо дерево.

scanf("%d", &n);
g.resize(n + 1);
for (i = 2; i <= n; i++)
{
  scanf("%d", &p);
  g[i].push_back(p);
  g[p].push_back(i);
}

Обчислюємо і виводимо результат.

res = dfs(1);
printf("%lld\n", res);