제출 #1338974

#제출 시각아이디문제언어결과실행 시간메모리
1338974ppmn_6Beads and wires (APIO14_beads)C++20
100 / 100
151 ms42728 KiB
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;

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

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;

template<class Key, class Compare = less<Key>>
using indexed_set = tree<Key, null_type, Compare, rb_tree_tag, tree_order_statistics_node_update>;

template<class Key, class Value, class Compare = less<Key>>
using indexed_map = tree<Key, Value, Compare, rb_tree_tag, tree_order_statistics_node_update>;

template<class Key>
using hash_set = gp_hash_table<
    Key, null_type, hash<Key>, equal_to<Key>, direct_mask_range_hashing<Key>, linear_probe_fn<>,
    hash_standard_resize_policy<hash_exponential_size_policy<>, hash_load_check_resize_trigger<true>, true>>;
    
template<class Key, class Value>
using hash_map = gp_hash_table<
    Key, Value, hash<Key>, equal_to<Key>, direct_mask_range_hashing<Key>, linear_probe_fn<>,
    hash_standard_resize_policy<hash_exponential_size_policy<>, hash_load_check_resize_trigger<true>, true>>;
 
// https://codeforces.com/blog/entry/79148
class Timer: chrono::high_resolution_clock {
    const time_point start_time;
public:
    Timer(): start_time(now()) {}
    rep elapsed_time() const {
		return chrono::duration_cast<chrono::milliseconds>(now() - start_time).count();
	}
} timer;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n, ans = 0;
	cin >> n;
	vector<vector<pair<int, int>>> tree(n + 1);
	vector<vector<int>> pf_max(n + 1), sf_max(n + 1);
	vector<int> dp0(n + 1, 0), dp1(n + 1, 0);
	for (int i = 1; i < n; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		tree[u].push_back({v, w});
		tree[v].push_back({u, w});
	}
	auto dfs = [&] (auto self, int u, int p)->void {
		int wp;
		for (auto &[v, w] : tree[u]) {
			if (v != p) {
				self(self, v, u);
				dp0[u] += max(dp0[v], dp1[v]);
			}
			else {
				wp = w;
			}
		}
		if (p) {
			for (auto &[v, w] : tree[u]) {
				if (v != p) {
					dp1[u] = max(dp1[u], wp + w + dp0[u] - max(dp0[v], dp1[v]) + dp0[v]);
				}
			}
		}
	};
	// pf/sf_max: w - max(dp0[v], dp1[v]) + dp0[v]
	auto reroot = [&] (int u, int pos)->void {
		int v = tree[u][pos].first;
		dp0[u] -= max(dp0[v], dp1[v]);
		dp1[u] = 0;
		if (pos) {
			dp1[u] = tree[u][pos].second + pf_max[u][pos - 1] + dp0[u];
		}
		if (pos < int(tree[u].size()) - 1) {
			dp1[u] = max(dp1[u], tree[u][pos].second + sf_max[u][pos + 1] + dp0[u]);
		}
		dp0[v] += max(dp0[u], dp1[u]);
		dp1[v] = 0;
	};
	auto dfs2 = [&] (auto self, int u, int p)->void {
		ans = max(ans, dp0[u]);
		pf_max[u].resize(tree[u].size());
		sf_max[u].resize(tree[u].size());
		for (int i = 0; i < tree[u].size(); i++) {
			auto &[v, w] = tree[u][i];
			pf_max[u][i] = sf_max[u][i] = w - max(dp0[v], dp1[v]) + dp0[v];
			if (i) {
				pf_max[u][i] = max(pf_max[u][i], pf_max[u][i - 1]);
			}
		}
		for (int i = int(tree[u].size()) - 2; i >= 0; i--) {
			sf_max[u][i] = max(sf_max[u][i], sf_max[u][i + 1]);
		}
		int pr;
		for (int i = 0; i < tree[u].size(); i++) {
			auto &[v, w] = tree[u][i];
			if (v != p) {
				reroot(u, i);
				self(self, v, u);
			}
			else {
				pr = i;
			}
		}
		if (u == 1) {
			return;
		}
		reroot(u, pr);
	};
	dfs(dfs, 1, 0);
	dfs2(dfs2, 1, 0);
	cout << ans;
	
	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...