Submission #471227

#TimeUsernameProblemLanguageResultExecution timeMemory
471227jalsol경주 (Race) (IOI11_race)C++17
100 / 100
596 ms30940 KiB
// looking to shine brighter in this world...

#define TASK "race"
#include "race.h"

#ifdef LOCAL
#include "local.h"
#else
#include <bits/stdc++.h>
#define debug(...)
#define DB(...)
#endif

using namespace std;

using ll = long long;
using ld = long double;

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define fi first
#define se second

#define For(i, l, r) for (int i = (l); i <= (r); ++i)
#define Ford(i, r, l) for (int i = (r); i >= (l); --i)
#define Rep(i, n) For (i, 0, (n) - 1)
#define Repd(i, n) Ford (i, (n) - 1, 0)
#define Fe(...) for (auto __VA_ARGS__)

template <class C> inline int isz(const C& c) { return static_cast<int>(c.size()); }
template <class T> inline bool chmin(T& a, const T& b) { return (a > b) ? a = b, true : false; }
template <class T> inline bool chmax(T& a, const T& b) { return (a < b) ? a = b, true : false; }

const bool __initialization = []() {
    cin.tie(nullptr)->sync_with_stdio(false);
    if (fopen(TASK".inp", "r")) {
        (void)(!freopen(TASK".inp", "r", stdin));
        (void)(!freopen(TASK".out", "w", stdout)); }
    cout << setprecision(12) << fixed;
    return true;
}();

constexpr ld eps = 1e-9;
constexpr int inf = 0x3f3f3f3f;
constexpr ll linf = 1e18;

// ================================================================================

constexpr int maxn = 2e5;
constexpr int maxk = 1e6 + 5;

int n, k;

struct Info { int v, c; };
vector<Info> g[maxn];

int sz[maxn];
bool rem[maxn];

int ans = inf;
int mindep[maxk];
enum { Get, Update, Clear };

int getSz(int u, int p) {
    sz[u] = 1;

    Fe (&[v, c] : g[u]) {
        if (v == p || rem[v]) continue;
        sz[u] += getSz(v, u);
    }

    return sz[u];
}

int getCen(int u, int sum, int p) {
    Fe (&[v, c] : g[u]) {
        if (v == p || rem[v]) continue;

        if (sz[v] * 2 > sum) {
            return getCen(v, sum, u);
        }
    }

    return u;
}

void calc(int u, int p, int task, int dep, int sum) {
    if (sum > k) return;

    switch (task) {
        case Get:
            chmin(ans, dep + mindep[k-sum]);
            break;

        case Update:
            chmin(mindep[sum], dep);
            break;

        case Clear:
            mindep[sum] = inf;
            break;

        default:
            assert(false);
    }

    Fe (&[v, c] : g[u]) {
        if (!rem[v] && v != p) {
            calc(v, u, task, dep + 1, sum + c);
        }
    }
}

void process(int u) {
    int cen = getCen(u, getSz(u, -1), -1);
    rem[cen] = true;
 
    Fe (&[v, c] : g[cen]) {
        if (!rem[v]) {
            calc(v, cen, Get, 1, c);
            calc(v, cen, Update, 1, c);
        }
    }

    Fe (&[v, c] : g[cen]) {
        if (!rem[v]) {
            calc(v, cen, Clear, 1, c);
        }
    }
 
    Fe (&[v, c] : g[cen]) {
        if (!rem[v]) {
            process(v);
        }
    }
}

int best_path(int N, int K, int h[][2], int l[]) {
    n = N, k = K;
    Rep (i, n - 1) {
        int u = h[i][0];
        int v = h[i][1];
        int c = l[i];

        g[u].push_back({ v, c });
        g[v].push_back({ u, c });
    }

    memset(mindep, 0x3f, sizeof(mindep));
    mindep[0] = 0;

    process(0);
    if (ans == inf) ans = -1;

    return ans;
}

#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...