Submission #1299807

#TimeUsernameProblemLanguageResultExecution timeMemory
1299807aicloCat in a tree (BOI17_catinatree)C++20
0 / 100
1 ms568 KiB
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 200005;
vector<int> g[MAXN];
int N, D;

// Funkcja rekurencyjna zwraca wektor dp[]
// dp[i] = maksymalna liczba zaznaczonych węzłów w poddrzewie,
// jeśli najbliższy zaznaczony węzeł w górę drzewa jest w odległości >= i
vector<int> dfs(int v, int par) {
    // dp[d] = maks liczba zaznaczonych w poddrzewie v przy odległości d do najbliższego markowanego w górę
    vector<int> dp(D+1, 0);

    for (int u : g[v]) {
        if (u == par) continue;
        vector<int> child = dfs(u, v);

        vector<int> new_dp(D+1, 0);
        for (int i = 0; i <= D; i++) {
            int best = 0;
            for (int j = 0; j <= D; j++) {
                int dist = min(D, i+1+j); // odległość do zaznaczonego w górę po połączeniu z dzieckiem
                best = max(best, dp[i] + child[j]);
            }
            new_dp[i] = best;
        }
        dp = new_dp;
    }

    // Opcja: zaznaczamy v (tylko jeśli odległość do zaznaczonego w górę >= D)
    if (D > 0) {
        dp[0] = 1; // v jest zaznaczone
        for (int u : g[v]) {
            if (u == par) continue;
            vector<int> child = dfs(u, v);
            dp[0] += child[D-1]; // w dzieciach odległość = D-1
        }
    } else {
        dp[0] = 1; // D = 0, można zaznaczyć wszystkie
    }

    return dp;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> N >> D;

    for (int i = 1; i < N; i++) {
        int p;
        cin >> p;
        g[p].push_back(i);
        g[i].push_back(p);
    }

    vector<int> res = dfs(0, -1);
    cout << *max_element(res.begin(), res.end()) << "\n";
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...