This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#define int long long
int h[200005];
int c[200005];
vector<int> adjl[200005];
int in_cycle[200005];
///pos, increase
set<pair<int,int> > func(int node, bool fin = true){
    set<pair<int,int> > res1;
    for (auto x : adjl[node]){
        if (in_cycle[x]) continue;
        auto res = func(x);
        if (res.size()>res1.size()) swap(res,res1);
        for (auto y : res){
            auto it = res1.lower_bound({y.first,-1});
            if (it!=res1.end() && (*it).first==y.first){
                int t = (*it).second;
                res1.erase(it);
                res1.insert({y.first,y.second+t});
            }
            else{
                res1.insert({y.first,y.second});
            }
        }
    }
    if (!fin) return res1;
    pair<int,int> to_insert = {h[node]+1,c[node]};
    int cursum = 0;
    auto it = res1.lower_bound({h[node]+1,-1});
    if (it!=res1.end() && (*it).first==to_insert.first){
        int t = (*it).second;
        res1.erase(it);
        res1.insert({to_insert.first,to_insert.second+t});
    }
    else{
        res1.insert(to_insert);
    }
    it = res1.lower_bound(to_insert);
    bool done = false;
    while (it!=res1.begin()){
        it--;
        cursum += (*it).second;
        int curpos = (*it).first;
        it = res1.erase(it);
        if (cursum >= c[node]){
            int rem = cursum-c[node];
            if (rem!=0){
                res1.insert({curpos,rem});
            }
            done = true;
            break;
        }
    }
    if (!done){
        if (cursum!=0){
            if ((!res1.empty()) && (*res1.begin()).first==0){
                cursum += (*res1.begin()).second;
                res1.erase(res1.begin());
                res1.insert({0,cursum});
            }
            else
                res1.insert({0,cursum});
        }
    }
    else{
        if ((!res1.empty()) && (*res1.begin()).first==0){
            int t = (*res1.begin()).second;
            res1.erase(res1.begin());
            res1.insert({0,c[node]+t});
        }
        else
            res1.insert({0,c[node]});
    }
    /*printf("node %lld, ret ",node);
    for (auto x : res1){
        printf("(%lld,%lld) ",x);
    }
    printf("\n");*/
    return res1;
}
int p[200005];
int vis[200005];
main(){
    int n;
    scanf("%lld",&n);
    for (int x = 1; x<=n; x++){
        int t;
        scanf("%lld%lld%lld",&t,&h[x],&c[x]);
        p[x] = t;
        adjl[t].push_back(x);
    }
    vector<pair<int,vector<int> > > roots;
    for (int x = 1; x<=n; x++){
        if (vis[x]) continue;
        int c1 = x, c2 = x;
        c1 = p[c1]; c2 = p[p[c2]];
        bool found = false;
        while (c1!=c2){
            if (vis[c1]) {
                found = true;
                break;
            }
            vis[c1] = true;
            c1 = p[c1]; c2 = p[p[c2]];
        }
        if (found||vis[c1]) continue;
        vis[c1] = true;
        in_cycle[c1] = true;
        vector<int> curcycle;
        c2 = p[c2];
        while (c2!=c1){
            curcycle.push_back(c2);
            vis[c2] = true;
            in_cycle[c2] = true;
            c2 = p[c2];
        }
        for (auto x : curcycle){
            for (auto y : adjl[x]){
                if (!in_cycle[y]){
                    adjl[c1].push_back(y);
                }
            }
        }
        curcycle.push_back(c1);
     /*   printf("cycle found: ");
        for (auto x : curcycle) printf("%lld ",x);
        printf("\n");*/
        roots.push_back({c1,curcycle});
    }
    int ans = 0;
    for (auto x : roots){
        int root = x.first;
        int curans = 0;
        vector<pair<int,int> >stuff;
        for (auto y : x.second){
            stuff.push_back({h[y],c[y]});
            curans += c[y];
        }
        auto res = func(root,false);
        int cur = 0;
        stuff.push_back({0,0});
        sort(stuff.begin(),stuff.end());
        vector<pair<int,int> > newstuff;
        for (int x = 0; x<stuff.size(); x++){
            if (x!=0 && stuff[x].first==newstuff.back().first){
                newstuff.back().second+=stuff[x].second;
            }
            else newstuff.push_back(stuff[x]);
        }
        swap(newstuff,stuff);
        auto it = res.begin();
        int best = 999999999999999999LL;
        for (auto val : stuff){
            while (it!=res.end() && (*it).first<=val.first){
                cur += (*it).second;
                it++;
            }
            best = min(best,cur+curans-val.second);
           // printf("try values %lld, %lld %lld\n",cur,val);
        }
        ans += best;
    }
    printf("%lld",ans);
}
Compilation message (stderr)
worst_reporter2.cpp:88:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
   88 | main(){
      | ^~~~
worst_reporter2.cpp: In function 'int main()':
worst_reporter2.cpp:149:26: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  149 |         for (int x = 0; x<stuff.size(); x++){
      |                         ~^~~~~~~~~~~~~
worst_reporter2.cpp:90:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   90 |     scanf("%lld",&n);
      |     ~~~~~^~~~~~~~~~~
worst_reporter2.cpp:93:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   93 |         scanf("%lld%lld%lld",&t,&h[x],&c[x]);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |