Submission #978882

# Submission time Handle Problem Language Result Execution time Memory
978882 2024-05-09T23:50:35 Z lucas Race (IOI11_race) C++17
Compilation error
0 ms 0 KB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;

#define F0R(i,n) for (int i = 0; i < n; i++)
#define FOR(i,a,b) for (int i = a; i <= b; i++)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define FORd(i,a,b) for (int i = (b); i >= (a); i--)
#define trav(a, x) for (auto& a : x)
#define rep(i, a, b) for(int i = a; i < (b); ++i)

#define f first
#define s second
#define mp make_pair
#define pb push_back
#define ins insert
#define lb lower_bound
#define ub upper_bound
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()

const char nl = '\n';
const int MAX_N = 100011;
const ll INF = (1<<29) + 123;
const ll MOD = 1000000007; // 998244353
const ld PI = 4*atan((ld)1);

template <typename T> bool ckmin(T& a, const T& b) { return a > b ? a=b, 1 : 0; }
template <typename T> bool ckmax(T& a, const T& b) { return b > a ? a=b, 1 : 0; }

/**** Credit to chatgpt 4.0 ****/

// Stream operator for std::pair
template<typename T1, typename T2>
ostream& operator<<(ostream &out, const pair<T1, T2> &v) {
    out << "(" << v.first << ", " << v.second << ")"; 
    return out;
}

// Trait to check if a type is iterable
template<typename T, typename = void>
struct is_iterable : false_type {};

template<typename T>
struct is_iterable<T, void_t<decltype(begin(declval<T>())), decltype(end(declval<T>()))>> : true_type {};

// Stream operator for iterable types excluding std::string
template<typename TT>
typename enable_if<is_iterable<TT>::value && !is_same<TT, string>::value, ostream&>::type
operator<<(ostream& out, const TT& c) {
    out << "{ ";
    for (const auto& x : c) out << x << " ";
    out << "}"; 
    return out;
}

template<typename T>
ostream& operator<<(ostream& out, std::stack<T> container) {
    std::vector<T> elements;
    while (!container.empty()) {
        elements.push_back(container.top());
        container.pop();
    }
    std::reverse(elements.begin(), elements.end()); // Reverse to maintain order
    return out << elements;
}

template<typename T>
ostream& operator<<(ostream& out, std::queue<T> container) {
    std::vector<T> elements;
    while (!container.empty()) {
        elements.push_back(container.front());
        container.pop();
    }
    return out << elements;
}

// Helper function to print std::priority_queue
template<typename T, typename Container, typename Compare>
ostream& operator<<(ostream& out, std::priority_queue<T, Container, Compare> pq) {
    out << "{";
    while (!pq.empty()) {
        out << " " << pq.top();
        pq.pop();
    }
    out << " }";
    return out;
}

#ifdef DBG
void dbg_out() { cerr << endl; }

template<typename Head, typename... Tail>
void dbg_out(Head H, Tail... T) {
    cerr << ' ' << H;
    dbg_out(T...);
}

#define dbg(...) cerr << #__VA_ARGS__ << ":", dbg_out(__VA_ARGS__);
#define dbg_array(a, n) cerr << #a << ": { "; for(int i = 0; i < n; i++) cerr << a[i] << " "; cerr << "}\n";
#else
#define dbg(...)
#define dbg_array(a, n)
#endif

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

const int MX = 2e5+5;

int n;
vpi adj[MX];
vector<bool> dead(MX, 0);
int subtree_size[MX];

int get_subtree_size(int node, int parent = -1) {
    if (dead[node]) {
        subtree_size[node] = 0;
        return 0;
    }
	int &res = subtree_size[node];
	res = 1;
	for (pi i : adj[node]) {
		if (i.f == parent) { continue; }
		res += get_subtree_size(i.f, node);
	}
	return res;
}

int get_centroid(int node, int parent = -1) {
    if (dead[node]) assert(0);
	for (pi i : adj[node]) {
		if (i.f == parent) { continue; }

		if (subtree_size[i.f] * 2 > subtree_size[node]) { return get_centroid(i.f, node); }
	}
	return node;
}

array<int, 3> dist[MX]; // dist, length, child root
vi comp;
const int maxK = 1e6+5;
void calc_dist(int node, int depth, int par, int d, int root = -1) {
    dbg("calc_dist", node, depth, par, d, root, dead[node]);
    if (dead[node]) return;
    if (d >= maxK) return;
    comp.pb(node);
    dist[node] = {d, depth, root};
    trav(u, adj[node]) {
        if (u.f == par) continue;
        int newRoot = root;
        if (root == -1) newRoot = u.f;
        calc_dist(u.f, depth+1, node, d+u.s, newRoot);
    }
}

int k;
int ans = MX;
vpi cnt[maxK];  // map from dist to pair of depth, childNode
void solve(int node) {
    if (dead[node]) return;
    get_subtree_size(node);
    int cent = get_centroid(node);
    dbg(node, cent);
    // dfs on cent and store all the lengths
    comp.clear();
    calc_dist(cent, 0, -1, 0);
    dbg(comp);
    // now two sum the component
    trav(v, comp) {
        assert(dist[v][0] < maxK);
        cnt[dist[v][0]].clear();
    }
    trav(v, comp) {
        if (v == cent) continue;
        dbg(dist[v][0], dist[v][1], dist[v][2]);
        if (dist[v][0] < maxK)
            cnt[dist[v][0]].pb({dist[v][1], dist[v][2]});
    }
    trav(v, comp) {
        int d = dist[v][0];
        if (d >= maxK) continue;
        sort(all(cnt[d]));
        vpi tmp;
        int taken = -1;
        // find the first two not from the same childNode
        trav(x, cnt[d]) {
            if (taken == -1) {
                tmp.pb(x);
                taken = x.s;
            } else if (taken != x.s) {
                tmp.pb(x);
                break;
            }
        }
        assert(sz(tmp) <= 2);
        cnt[dist[v][0]] = tmp;
        dbg(d, cnt[d]);
    }
    // now two sum on this
    trav(v, comp) {
        int d = dist[v][0];
        if (d >= maxK) continue;
        if (d == k) {
            assert(sz(cnt[d]) > 0);
            ckmin(ans, cnt[d][0].f);
        }
        int rem = k-d;
        if (rem < 0) continue;
        if (!sz(cnt[rem])) continue;
        trav(x, cnt[d]) {
            trav(y, cnt[rem]) {
                if (x.s != y.s) {
                    ckmin(ans, x.f+y.f);
                }
            }
        }
    }
    dbg("marking dead", cent);
    dead[cent] = 1;
    trav(u, adj[cent]) {
        solve(u.f);
    }
}

int best_path(int N, int K, int H[][2], int L[]) {
    n = N;
    k = K;
    F0R(i, N-1) {
        adj[H[i][0]].pb({H[i][1], L[i]});
        adj[H[i][1]].pb({H[i][0], L[i]});
    }
    solve(0);
    if (ans == MX) return -1;
    return ans;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n, k; cin >> n >> k;
    int H[n-1][2]; F0R(i, n-1) cin >> H[i][0] >> H[i][1];
    int L[n-1]; F0R(i, n-1) cin >> L[i];
    cout << best_path(n, k, H, L) << nl;
    return 0;
}

Compilation message

/usr/bin/ld: /tmp/ccJ0szVS.o: in function `main':
race.cpp:(.text.startup+0x0): multiple definition of `main'; /tmp/cc0eTdZU.o:grader.cpp:(.text.startup+0x0): first defined here
collect2: error: ld returned 1 exit status