#include #include using namespace std; using namespace atcoder; using ll = long long; using mint = modint998244353; // using mint = modint1000000007; template using vec = vector; template using pa = pair; template using mipq = priority_queue, greater>; #define REP(_1, _2, _3, _4, name, ...) name #define REP1(i, n) for (auto i = decay_t{}; (i) < (n); ++(i)) #define REP2(i, l, r) for (auto i = (l); (i) < (r); ++(i)) #define REP3(i, l, r, d) for (auto i = (l); (i) < (r); i += (d)) #define rep(...) REP(__VA_ARGS__, REP3, REP2, REP1)(__VA_ARGS__) #define rrep(i, r, l) for (int i = (r); i >= (l); --i) template bool chmax(T &a, const T &b) { return (a < b ? a = b, true : false); } template bool chmin(T &a, const T &b) { return (a > b ? a = b, true : false); } constexpr int INF = 1 << 30; constexpr ll LINF = 1LL << 60; constexpr int mov[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; void solve(); int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << fixed << setprecision(15); int T = 1; // cin >> T; while (T--) solve(); } // 木dp的ななにか...? // 根をコスト付きで塗るか場合分けする // dpで計算するのは、親が塗られてたとき/塗られてないときの最小コスト // 根を塗るなら、ぜんぶで親が塗られてたときのコストになる // 根を塗らないなら、まず過半数を塗る必要があって(ここで親が塗られてた/塗られてないの差が発生)、 // 残りは塗られてたときのコストでできる // うーん、ほんとか?根の選択に依存しないのか? // よさそうな雰囲気はある、順番があまり関係しないから...? void solve() { int N; cin >> N; vec> G(N); rep(i, N - 1) { int u, v; cin >> u >> v; u--; v--; G[u].push_back(v); G[v].push_back(u); } auto dfs = [&] (this auto self, int u, int p) -> pa { // 過半数を選ぶ部分では、根が塗られたときの差分が小さいやつをたくさん選べばいい int s = 0; vec diff; for (auto v : G[u]) { if (v == p) continue; auto [c1, c2] = self(v, u); s += c1; diff.push_back(c1 - c2); } int n = diff.size(); ranges::sort(diff); vec cum(n + 1); rep(i, n) cum[i + 1] = cum[i] + diff[i]; int d = n + (p != -1), res1 = s + 1 - cum[n], res2 = res1; if (d / 2 < n) chmin(res1, s - (cum[n] - cum[d / 2 + 1])); chmin(res2, s - (cum[n] - cum[d / 2])); return {res1, res2}; }; cout << dfs(0, -1).first << '\n'; }