Submission #77477

#TimeUsernameProblemLanguageResultExecution timeMemory
77477qkxwsmBeads and wires (APIO14_beads)C++17
100 / 100
257 ms19984 KiB
/* _____ .' '. / 0 0 \ | ^ | | \ / | \ '---' / '._____.' */ #include <bits/stdc++.h> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> using namespace std; using namespace __gnu_pbds; struct chash { int operator()(int x) const { x ^= (x >> 20) ^ (x >> 12); return x ^ (x >> 7) ^ (x >> 4); } }; template<typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; template<typename T, typename U> using hashtable = gp_hash_table<T, U, chash>; random_device(rd); mt19937 rng(rd()); template<class T> void readi(T &x) { T input = 0; bool negative = false; char c = ' '; while (c < '-') { c = getchar(); } if (c == '-') { negative = true; c = getchar(); } while (c >= '0') { input = input * 10 + (c - '0'); c = getchar(); } if (negative) { input = -input; } x = input; } template<class T> void printi(T output) { if (output == 0) { putchar('0'); return; } if (output < 0) { putchar('-'); output = -output; } int aout[20]; int ilen = 0; while(output) { aout[ilen] = ((output % 10)); output /= 10; ilen++; } for (int i = ilen - 1; i >= 0; i--) { putchar(aout[i] + '0'); } return; } template<class T> void ckmin(T &a, T b) { a = min(a, b); } template<class T> void ckmax(T &a, T b) { a = max(a, b); } template<class T, class U> T nmod(T &x, U mod) { if (x >= mod) x -= mod; } template<class T> T gcd(T a, T b) { return (b ? gcd(b, a % b) : a); } template<class T> T randomize(T mod) { return (uniform_int_distribution<T>(0, mod - 1))(rng); } #define y0 ___y0 #define y1 ___y1 #define MP make_pair #define MT make_tuple #define PB push_back #define PF push_front #define LB lower_bound #define UB upper_bound #define fi first #define se second #define debug(x) cerr << #x << " = " << x << endl; const long double PI = 4.0 * atan(1.0); const long double EPS = 1e-10; #define MAGIC 347 #define SINF 10007 #define CO 1000007 #define INF 1000000007 #define BIG 1000000931 #define LARGE 1696969696967ll #define GIANT 2564008813937411ll #define LLINF 2696969696969696969ll #define MAXN 200013 typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef pair<ld, ld> pdd; int N; vector<pii> edge[MAXN]; int parent[MAXN], dup[MAXN]; vector<int> ord; int res[2][2]; int dp[MAXN][2][2]; int mx0 = -INF, mx1 = -INF; void dfs(int u) { for (pii p : edge[u]) { int d = p.fi, v = p.se; if (v == parent[u]) { continue; } parent[v] = u; dup[v] = d; dfs(v); } ord.PB(u); } void init() { res[0][0] = 0; res[0][1] = 0; res[1][0] = 0; res[1][1] = 0; mx0 = -INF; mx1 = -INF; } void assign(int u) { ckmax(dp[u][0][0], res[0][0]); ckmax(dp[u][0][1], res[0][1]); ckmax(dp[u][1][0], res[1][0]); ckmax(dp[u][1][1], res[1][1]); } int32_t main() { ios_base::sync_with_stdio(0); // cout << fixed << setprecision(10); // cerr << fixed << setprecision(10); // freopen ("file.in", "r", stdin); // freopen ("file.out", "w", stdout); cin >> N; for (int i = 1; i < N; i++) { int u, v, d; cin >> u >> v >> d; u--; v--; edge[u].PB({d, v}); edge[v].PB({d, u}); } parent[0] = N; dup[0] = -INF; dfs(0); for (int i = 0; i < N; i++) { int u = ord[i]; // cerr << u << endl; //dp[vertex][taking only guy to parent][have u gotten a cut] // res[1][0] = dup[u] + sum over all v of dp[v][0][0] // res[1][1] = dup[u] + sum over all v of dp[v][0][1] for (pii p : edge[u]) { int v = p.se; if (v == parent[u]) continue; res[0][0] += dp[v][0][0]; res[0][1] += dp[v][0][0]; ckmax(mx1, dp[v][0][1] - dp[v][0][0]); } res[0][1] += mx1; res[1][0] = res[0][0] + dup[u]; res[1][1] = res[0][1] + dup[u]; assign(u); init(); //if u dont take u, then: //res[0][0] = sum over all v of dp[v][0][0] //res[0][1] = sum over all v of dp[v][0][1] //if u take two chidlren of u: it's always ok //res[0][1] = sum over all v except 2 of dp[v][0][1] plus the two dp[v][1]][1] int sum = 0; //u choose vertices v1, v2 and v3 and take dp[v1][1][0] + dp[v2][1][1] + dp[rest][0][0] for (pii p : edge[u]) { int v = p.se; if (v == parent[u]) continue; int dif = dp[v][1][0] - dp[v][0][0]; if (dif > mx0) { mx1 = mx0; mx0 = dif; } else if (dif > mx1) { mx1 = dif; } sum += dp[v][0][0]; } for (pii p : edge[u]) { int v = p.se; if (v == parent[u]) continue; ckmax(res[0][1], (dp[v][1][1] - dp[v][0][0]) + ((dp[v][1][0] - dp[v][0][0] == mx0) ? mx1 : mx0) + sum); } res[1][1] = res[0][1] + dup[u]; assign(u); init(); //if u take one child of u and v //res[0][0] = sum over all v except 1 of dp[v][0][0] plus dp[v][1][0] + dup[u] //res[0][1] = sum over all v except 1 of dp[v][0][0] plus dp[v][1][1] + dup[u] res[0][0] = dup[u]; res[0][1] = dup[u]; for (pii p : edge[u]) { int v = p.se; if (v == parent[u]) continue; res[0][0] += dp[v][0][0]; res[0][1] += dp[v][0][0]; ckmax(mx0, dp[v][1][0] - dp[v][0][0]); ckmax(mx1, dp[v][1][1] - dp[v][0][0]); } res[0][0] += mx0; res[0][1] += mx1; assign(u); init(); //u just take nothing ckmax(dp[u][1][1], dp[u][1][0]); ckmax(dp[u][0][1], dp[u][0][0]); // cerr << "vertex " << u << ' ' << dp[u][0][0] << ' ' << dp[u][0][1] << ' ' << dp[u][1][0] << ' ' << dp[u][1][1] << endl; } cout << dp[0][0][1] << '\n'; //possibilities: u took 1 or u havent //ur subtree is stupid or its not //the path between anytwo endpoints must go through a third point? // cerr << "time elapsed = " << (clock() / (CLOCKS_PER_SEC / 1000)) << " ms" << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...