Submission #1246944

#TimeUsernameProblemLanguageResultExecution timeMemory
1246944KindaGoodGamesMagic Tree (CEOI19_magictree)C++20
47 / 100
656 ms1114112 KiB
#include<bits/stdc++.h>

using namespace std;
#define int long long
#define pii pair<int,int>
#define tiii tuple<int,int,int>

int n, m, k;
vector<pii> fruits;
vector<vector<int>> adj;

vector<vector<int>> dp;
void DFS(int v, int p){
    for(auto u : adj[v]){
        if(u == p) continue;
        DFS(u,v);
    }

    for(int t = 1; t <= k; t++){
        int s = 0;
        for(auto u : adj[v]){
            s += dp[t][u];
        }

        int add = 0;
        if(t == fruits[v].first){
            add += fruits[v].second;
        }
        dp[t][v] = max(s + add, dp[t-1][v]);
    }
} 

vector<vector<int>> adjP; 
vector<pii> edges;
void findPar(int v, int p, int fp){
    if(v != p && fruits[v].second != 0) {
        edges.push_back({v,p});
    }
    if(fruits[v].second != 0){
        p = v;
    }
    for(auto u : adjP[v]){
        if(u == fp){
            continue;
        }
        findPar(u   ,p,v);
    }
}

int32_t main(){
    cin >> n >> m >> k;

    fruits.resize(n);
    adjP.resize(n);

    map<int,int> rp;
    vector<int> par(n);
    vector<int> in(n);
    vector<tiii> fruitsRaw(m);
    
    for(int i = 1; i < n; i++){
        int p;
        cin >> p;
        p--;
        adjP[i].push_back(p);
        adjP[p].push_back(i);
    } 


    #pragma region coordinate compression
    {
        set<int> times;
        for(int i = 0; i <m; i++){
            int v, d, w;
            cin >> v >> d >>w;
            v--;
            fruits[v] = {d,w};
            fruitsRaw[i] = {v,d,w};
            times.insert(d);
        } 
        times.insert(0);
        vector<int> sorted(times.begin(),times.end());
        
        map<int,int> toInd;
        for(int i = 0; i < sorted.size(); i++){
            toInd[sorted[i]] = i;
        }

        for(int i = 0; i < n; i++){ 
            fruits[i].first = toInd[fruits[i].first]; 
        }
        for(int i = 0; i < m; i++){
            int v,d,w;
            tie(v,d,w) = fruitsRaw[i];
            fruitsRaw[i] = {v,toInd[d],w}; 
        }
        k = toInd.size();
    }
    #pragma endregion

    findPar(0,0,0);

    // do it again

    set<int> occ;
    for(int i = 0; i < edges.size(); i++){
        occ.insert(edges[i].first);
        occ.insert(edges[i].second);
    }
    vector<int> sorted(occ.begin(),occ.end());
        
    map<int,int> toInd;
    for(int i = 0; i < sorted.size(); i++){
        toInd[sorted[i]] = i;
    }
    for(int i = 0; i < edges.size(); i++){
        edges[i] = {toInd[edges[i].first],toInd[edges[i].second]};  
    }
    n = toInd.size();
    
    // recalibrate
    adj.resize(n);

    for(int i = 0; i < edges.size(); i++){
       adj[edges[i].first].push_back(edges[i].second);
       adj[edges[i].second].push_back(edges[i].first);
    }
    fruits = vector<pii>(n);
    for(int i = 0; i < m; i++){
        int v,d,w;
        tie(v,d,w) = fruitsRaw[i];

        fruits[toInd[v]] = {d,w};
    }

    dp.resize(k+1, vector<int>(n));
    DFS(0,0);
    cout << dp[k][0] << endl;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...