250032026-02-17 11:50:26ubormaciTársaság (50)cpp17Wrong answer 7/507ms1084 KiB
#include <iostream>
#include <algorithm> // for sort, mainly
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <array>
#include <string>
#include <cstdio>
#include <iterator>
#include <unordered_set>
#include <cstdint> // for int64_t, int32_t, etc
#include <queue>
#include <stack>
#include <deque>
#include <numeric> // gcd, lcm
#include <fstream>
#include <bitset> // for bitset
#include <iomanip>
#include <cassert> // for set with custom ordering
#include <type_traits> // for set with custom ordering
#include <utility> // for swap, forward, etc
using namespace std;

#pragma GCC optimize("O2")
// #pragma GCC optimize("O1","O2","O3","Ofast","unroll-loops")
// #pragma GCC target("sse","sse2","sse3","sse4.1","sse4.2","avx","avx2","fma")

template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
template<typename T_container, typename T = typename enable_if<!is_same<T_container, string>::value, typename T_container::value_type>::type> ostream& operator<<(ostream &os, const T_container &v) { os << '{'; string sep; for (const T &x : v) os << sep << x, sep = ", "; return os << '}'; }
void dbg_out() { cout << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); }
#ifdef LOCAL
#define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define dbg(...)
#endif

/*

notes:

int64_t
stoi(string s) -> string to int
to_string() -> int (or else) to string

vector declaration:
vector<ll> v(n, 0)
vector<vector<ll>> v(n, vector<ll>(n, 0));

{if statement} ? {truth value} : {false value}

#ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif

std::lcm(ll a, ll b), std::gcd(int a, int b)

cout << fixed << setprecision(n);

set with custom ordering
set<ll, decltype(&cmp)> qu(cmp);

*/

typedef int64_t ll;

/*

Two seemingly contradictory cases

(using parent child weight)
k = 1
1 2 1
2 3 10

on this, my first method of deleting the edges with the largest weight would work
however, the second of sorting nodes based on the total maximal distance in them would not

but on this
k = 2
1 2 6
2 3 5
1 4 4
4 5 4

that one would work perfectly


*/

bool check(ll mx, ll k, ll n, vector<ll> &p, vector<ll> &pd, vector<vector<ll>> &ch, vector<bool> leaf, vector<ll> in) {

    // megnezzuk, hany elet kene-e levagjunk
    // hogy a maximum x vagy kisebb legyen
    // ha ez a szam nagyobb mint k, nem lehet
    // ha kisebb, lehet

    // megyunk top-down
    // megnezzuk, ha egy gyerektol tul nagy lenne az ido
    // akkor azt levagjuk, nyissz

    ll cuts = 0;

    /*
    
    es itt az a kerdes, hogy fentrol lefele megyunk-e
    es en azt mondom, lentrol felfele
    mert figyelj ide:

              1
            /  \
           2    5
         /  \    \ 
        3   4     6

        minden el sulya 10
        ha fentrol jovunk, es mohon vesszuk
        akkor k = 2-re nem jon ki
        mert elvagja a 2-3, 2-4-et
        es aztan nem marad az 1-5-re

        de ha lentrol jovunk
        elvagja az 1-2-et, es az 1-5-t

    */
    
    vector<ll> dh(n+1, 0);

    queue<ll> q;
    for(ll i = 1; i <= n; i++) {
        if(leaf[i]) {
            q.push(i);
        }
    }

    while(!q.empty()) {

        ll curr = q.front();
        q.pop();

        // ha innen a szulojeig, tobb lenne mint mx, akkor kell egy cut

        if(dh[curr] + pd[curr] > mx) {
            cuts++;
        }else{
            dh[p[curr]] = max(dh[p[curr]], dh[curr] + pd[curr]);
        }

        in[p[curr]]--;
        if(in[p[curr]] == 0) {
            q.push(p[curr]);
        }
    }

    if(cuts <= k) {
        return true;
    }else{
        return false;
    }
}

void solve() {

	ll n, k;
	cin >> n >> k;
    vector<ll> p(n+1, 0); // parent
    vector<ll> pd(n+1, 0); // parent distance	
	vector<vector<ll>> ch(n+1); // children count

    vector<ll> in(n+1, 0);

	vector<bool> leaf(n+1, true); // stores for each whether it's a leaf

	for(ll i = 2; i <= n; i++) {
		cin >> p[i] >> pd[i];

        in[p[i]]++;

		leaf[p[i]] = false;
		ch[p[i]].push_back(i);
	}

    // let's do a binary search
    // why not
    // (I checked someone else's solution)

    // binary search for the smallest value which we can achieve
    // using k or less cuts
    // this is a first

    if(k == n - 1) {
        cout << "0\n";
        return;
    }
    // eset lekezelve

    // l biztos nem lehet, r biztos lehet
    // first true binary search
    ll l = 0, r = 100;
    while(l < r) {

        //cerr << "\nl=" << l << "; r=" << r;

        ll mid = l + (r - l)/2;
        if(check(mid, k, n, p, pd, ch, leaf, in)) {
            r = mid;
        }else{
            l = mid+1;
        }
    }

    //cerr << "\nl=" << l;

    cout << l;

}	

int main()
{
	std::ios_base::sync_with_stdio(false);
	//cin.tie(nullptr);
	//cout.tie(nullptr);

	solve();

	return 0;
}
SubtaskSumTestVerdictTimeMemory
base7/50
1Accepted0/01ms500 KiB
2Wrong answer0/04ms820 KiB
3Wrong answer0/32ms384 KiB
4Wrong answer0/32ms316 KiB
5Accepted3/31ms428 KiB
6Wrong answer0/31ms316 KiB
7Wrong answer0/31ms316 KiB
8Wrong answer0/31ms324 KiB
9Wrong answer0/32ms564 KiB
10Wrong answer0/32ms600 KiB
11Wrong answer0/33ms564 KiB
12Wrong answer0/33ms824 KiB
13Wrong answer0/44ms820 KiB
14Wrong answer0/44ms1012 KiB
15Wrong answer0/44ms1076 KiB
16Accepted4/44ms944 KiB
17Wrong answer0/47ms1084 KiB