Yolların yaxşılaşdırılması#10684

Yolların yaxşılaşdırılması (Həll təhlili)

funksiyası vasitəsilə zirvəsi köklü olan alt ağacda yolların keyfiyyətini yaxşılaşdırmağın neçə üsulu olduğunu bildirək. ilə zirvəsinin övladını işarə edək.

Tutaq ki, to_1, to_2, ..., to_k — -nin övladlarıdır. O zaman

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

Əgər yarpaqdırsa (övladı olmayan zirvə), onda f(v) = 1 qoyaq.

Nümunə

Şərtdə verilmiş nümunələri nəzərdən keçirək. Hər bir zirvəsi üçün qiymətini yazacağıq.

Birinci nümunədə yolların keyfiyyətini yaxşılaşdırmağın üsulu mövcuddur ki, bu da hər hansı bir şəhərdən -ə qədər olan yolda ən çoxu bir pis yolun mövcud olduğu vəziyyətləri təmsil edir. Pis yollar qırıq xəttlərlə, yaxşı yollar isə dəstəklərlə göstərilib.

Alqoritmin tətbiqi

Bütün hesablama əməliyyatları MOD = 10^9 + 7 moduluna əsasən həyata keçirilir.

#define MOD 1000000007

dfs funksiyası zirvəsi köklü olan alt ağacda yolların keyfiyyətini yaxşılaşdırmağın neçə üsulu olduğunu bildirən funksiyasının qiymətini hesablayır. zirvəsinin əcdadı olur.

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

Əgər to_1, to_2, ..., to_k — -nin övladlarıdırsa, onda

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;
}

Giriş məlumatlarını oxuyuruq. Ağacı qururuq.

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);
}

Nəticəni hesablamaq və çıxışa vermək.

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