// compile: make data
// run: ./data < data.in
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifdef LOCAL
#include <debug/codeforces.h>
#define debug(x...) _debug_print(#x, x);
#define Debug(x...) _debug_print_format(#x, x);
#else
#define debug(x...)
#define Debug(x...)
#endif
template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;}
#define VI vector<int>
#define VII vector<vector<int>>
#define VIII vector<vector<vector<int>>>
#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)
#define sz(v) ((int)(v).size())
#define print(...) print_(__VA_ARGS__);
#define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0)
#define cmin(x,...) x=min({(x), __VA_ARGS__})
#define cmax(x,...) x=max({(x), __VA_ARGS__})
#define INTMAX (int)(9223372036854775807)
#define INF (int)(1152921504606846976)
#define NaN (int)(0x8b88e1d0595d51d1)
#define double long double
#define int long long
#define MAXN 200010
struct Tree {
int n;
vector<vector<int>> el;
struct node {
vector<node*> ch;
node* parent;
int size;
};
vector<node> vertex;
node *root;
Tree(int V) {
n = V;
el.resize(n);
vertex.resize(n);
}
void add_edge(int u, int v) {
el[u].push_back(v), el[v].push_back(u);
}
void build(int rt = 0) {
function<void(int, int)> dfs = [&](int u, int pre) {
vertex[u].size = 1;
for (int v: el[u]) {
if (v == pre) continue;
vertex[u].ch.push_back(&vertex[v]);
vertex[v].parent = &vertex[u];
dfs(v, u);
vertex[u].size += vertex[v].size;
}
};
root = &vertex[rt];
dfs(rt, -1);
}
int ind(node *x) {return x - &vertex[0]; }
void graphviz_dump(int plus = 0, string filename = "graph.dot") {
FILE *f = fopen(filename.c_str(), "w");
fprintf(f, "digraph Tree {\n");
rep(i, 0, n) {
node *x = &vertex[i];
fprintf(f, " %lld;\n");
}
rep(i, 0, n) {
node *x = &vertex[i];
for (auto y: x->ch) {
fprintf(f, " %ld -> %ld;\n", x - &vertex[0], y - &vertex[0]);
}
}
fprintf(f, "}\n");
}
int solve() {
// 0: no edge
// 1: has edge
vector<vector<int>> dp(n, vector<int>(2, 0));
function<void(node*)> dfs = [&](node *x) {
if (!x->ch.size()) return;
int maxv = -INF;
for (auto c: x->ch) {
dfs(c);
dp[ind(x)][0] += max(dp[ind(c)][0], dp[ind(c)][1]);
cmax(maxv, dp[ind(c)][0] - max(dp[ind(c)][0], dp[ind(c)][1]) + 1);
}
dp[ind(x)][1] = dp[ind(x)][0] + maxv;
};
dfs(root);
return max(dp[ind(root)][0], dp[ind(root)][1]);
}
};
int32_t main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int n; cin >> n;
Tree g(n);
rep(i, 0, n-1) {
int u, v; cin >> u >> v;
g.add_edge(u-1, v-1);
}
g.build(0);
cout << g.solve() << endl;
return 0;
}
Downloading the app was super easy and now I carry my favorite casino games right in my pocket. The graphics are crystal clear and every spin feels completely fair. I love how they constantly add fresh titles to keep things exciting. Go ahead and grab your free spins because you absolutely deserve this treat. 789slotsapk
This has quickly become my favorite destination for evening games. The UI is clean, games are tested for fairness, and I actually get to see my winnings hit my wallet same day. bdvc6666
Just tried out this platform and the whole experience feels incredibly smooth. The slot collection keeps me entertained for hours and withdrawals hit my account faster than I expected. If you are looking for a reliable spot to play without stress, give this a shot. bajeevip23