250032026-02-17 11:50:26ubormaciTársaság (50)cpp17Hibás válasz 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;
}
RészfeladatÖsszpontTesztVerdiktIdőMemória
base7/50
1Elfogadva0/01ms500 KiB
2Hibás válasz0/04ms820 KiB
3Hibás válasz0/32ms384 KiB
4Hibás válasz0/32ms316 KiB
5Elfogadva3/31ms428 KiB
6Hibás válasz0/31ms316 KiB
7Hibás válasz0/31ms316 KiB
8Hibás válasz0/31ms324 KiB
9Hibás válasz0/32ms564 KiB
10Hibás válasz0/32ms600 KiB
11Hibás válasz0/33ms564 KiB
12Hibás válasz0/33ms824 KiB
13Hibás válasz0/44ms820 KiB
14Hibás válasz0/44ms1012 KiB
15Hibás válasz0/44ms1076 KiB
16Elfogadva4/44ms944 KiB
17Hibás válasz0/47ms1084 KiB