Link to this code:
https://cses.fi/paste/0da325cf18b78d5beb0dea//*
JAI JAGANNATH!
*/
//@Author : zanj0
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
template <class T>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
// #define LOCAL // ← enable locally via -DLOCAL; keep commented for OJ
#define ff first
#define ss second
#define pb push_back
#define MOD 1000000007
#define inf 1000000000000000000LL
#define ps(x, y) fixed << setprecision(y) << x
#define w(x) \
int x; \
cin >> x; \
while (x--)
#define endl "\n"
#define timetaken cerr << "Time : " << 1000 * (long double)clock() / (long double)CLOCKS_PER_SEC << "ms\n"
typedef long long int lli;
#ifdef LOCAL
#define dbg(x) cerr << "[DBG] " << #x << " = " << (x) << '\n'
template <class A, class B>
ostream &operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ',' << p.second << ')'; }
template <class T>
ostream &operator<<(ostream &os, const vector<T> &v)
{
os << '[';
for (size_t i = 0; i < v.size(); ++i)
{
if (i)
os << ',';
os << v[i];
}
return os << ']';
}
template <class K, class V>
ostream &operator<<(ostream &os, const map<K, V> &mp)
{
os << '{';
bool first = true;
for (const auto &kv : mp)
{
if (!first)
os << ',';
first = false;
os << kv.first << ':' << kv.second;
}
return os << '}';
}
template <class K, class V>
ostream &operator<<(ostream &os, const unordered_map<K, V> &mp)
{
os << '{';
bool first = true;
for (const auto &kv : mp)
{
if (!first)
os << ',';
first = false;
os << kv.first << ':' << kv.second;
}
return os << '}';
}
#else
#define dbg(x) ((void)0)
#endif
void zanj0()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef LOCAL
freopen("input.txt", "r", stdin);
#endif
}
/*
────────────────────────────────────────────────────────────────────────
Problem Statement:
Observations:
Claims:
────────────────────────────────────────────────────────────────────────
*/
lli GetSum(lli l, lli r, vector<lli>& v){
return v[r] - (l ? v[l - 1] : 0);
}
void Dfs(lli node, lli par,vector<vector<lli>>& graph, vector<vector<lli>>& dp){
vector<lli> dp_0;
vector<lli> dp_1;
for(auto& it : graph[node]){
if(it != par){
Dfs(it, node, graph, dp);
dp[node][0] += dp[it][1];
dp_0.pb(dp[it][0]);
dp_1.pb(dp[it][1]);
}
}
for(int i = 1; i < dp_1.size(); i++){
dp_1[i] += dp_1[i - 1];
}
for(int i = 0; i < dp_1.size(); i++){
lli now = 1 + dp_0[i];
if(i) now += GetSum(0, i - 1, dp_1);
if(i + 1 < dp_1.size()) now += GetSum(i + 1, dp_1.size() - 1, dp_1);
dp[node][1] = max(dp[node][1], now);
}
}
void Solve()
{
lli n;
cin >> n;
vector<vector<lli>> graph(n + 1);
for(int i = 0, u, v; i < (n - 1); i++){
cin >> u >> v;
graph[u].pb(v);
graph[v].pb(u);
}
vector<vector<lli>> dp(n + 1, vector<lli>(2));
Dfs(1, 0, graph, dp);
cout << dp[1][1] << endl;
}
int32_t main()
{
zanj0();
Solve();
timetaken;
return 0;
}
/*
GOLDEN RULES
• Solutions are simple.
• Proofs are simple.
• Implementations are simple.
*/