Submission #1362376

#TimeUsernameProblemLanguageResultExecution timeMemory
1362376alexddWorst Reporter 4 (JOI21_worst_reporter4)C++20
79 / 100
351 ms170828 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long

const int MAXN = 2e5 + 5;
const int MAXV = 1e9 + 2;

int n;
int parent[MAXN], h[MAXN], c[MAXN];
vector<int> con[MAXN];

bool oncyc[MAXN], done[MAXN];

map<int,int> difdp[MAXN];
void dfs(int nod)
{
    assert(!done[nod]);
    done[nod] = 1;

    int maxc = -1, heavy = -1;
    for(int adj:con[nod])
    {
        if(oncyc[adj])
            continue;

        dfs(adj);
        if((int)difdp[adj].size() > maxc)
            maxc = (int)difdp[adj].size(), heavy = adj;
    }

    if(heavy == -1)
    {
        difdp[nod].clear();

        difdp[nod][h[nod]] = 0;
        difdp[nod][h[nod] + 1] = c[nod];
        difdp[nod][MAXV] = 0;
    }
    else
    {
        swap(difdp[nod], difdp[heavy]);
        for(int adj:con[nod])
        {
            if(oncyc[adj] || adj == heavy)
                continue;
            for(auto it:difdp[adj])
            {
                difdp[nod][it.first] += it.second;
            }
        }

        if(oncyc[nod])
            return;

        difdp[nod][1] += c[nod];

        int ramas = c[nod];
        auto it = difdp[nod].upper_bound(h[nod]);
        assert(it != difdp[nod].begin());
        it--;
        assert(it != difdp[nod].end());
        while(ramas > 0)
        {
            int mnm = min(ramas, (*it).second);
            (*it).second -= mnm;
            ramas -= mnm;
            if(ramas == 0)
                break;

            (*it).second = 0;
            it = difdp[nod].erase(it);
            assert(it != difdp[nod].begin());
            it--;
        }

        difdp[nod][h[nod] + 1] += c[nod];
    }
}

void solve_tree()
{
    for(int i=2;i<=n;i++)
        con[parent[i]].push_back(i);
    dfs(1);
    cout<<difdp[1][1];
}

int visited[MAXN], pas;

signed main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>parent[i]>>h[i]>>c[i];
        con[parent[i]].push_back(i);
    }

    //solve_tree();

    int rez = 0;

    for(int i=1;i<=n;i++)
    {
        if(done[i])
            continue;
        int cur = i;
        pas++;
        while(visited[cur] != pas)
        {
            visited[cur] = pas;
            cur = parent[cur];
        }

        int capat = cur;
        vector<int> cyc;
        while(1)
        {
            cyc.push_back(cur);
            cur = parent[cur];
            if(cur == capat)
                break;
        }

        for(int x:cyc)
            oncyc[x] = 1;

        for(int x:cyc)
            dfs(x);

        int totc = 0;
        for(int x:cyc)
            totc += c[x];

        map<int,int> tot, sumc;
        for(int x:cyc)
        {
            sumc[h[x]] -= c[x];
            tot[h[x]] += 0;
            for(auto it:difdp[x])
                tot[it.first] += it.second;
        }

        int pref = 0;
        int aux = 1e18;
        for(auto it:tot)
        {
            pref += it.second;
            aux = min(aux, pref + (totc + sumc[it.first]));
        }

        rez += aux;
    }

    for(int i=1;i<=n;i++)
        assert(done[i]);

    cout<<rez;

    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...