#include <bits/stdc++.h>
using namespace std;
#define task "main"
#define F first
#define S second
#define ii pair<int, int>
#define il pair<int, long long>
#define li pair<long long, int>
#define FOR(i, a, b) for(int i = (a); i <= (b); ++i)
#define FOD(i, b, a) for(int i = (b); i >= (a); --i)
template <class T1, class T2>
bool maximize(T1 &a, T2 b){
if (a < b) {a = b; return true;}
return false;
}
template <class T1, class T2>
bool minimize(T1 &a, T2 b){
if (a > b) {a = b; return true;}
return false;
}
template <class T>
void printArr(T container, string separator = " ", string finish = "\n", ostream &out = cout){
for(auto item: container) out << item << separator;
out << finish;
}
const int MAX_N = (int)2e5 + 5;
const int INF = (int)1e9 + 1408;
int nNode;
vector<int> adj[MAX_N];
int sz[MAX_N];
int in[MAX_N], out[MAX_N], node[MAX_N];
int timer = 0;
struct IT {
multiset<int> tree[4 * MAX_N];
void build(int id, int l, int r) {
if (l == r) {
tree[id].insert(sz[node[l]]);
return;
}
int mid = (l + r) >> 1;
build(id << 1, l, mid);
build(id << 1 | 1, mid + 1, r);
tree[id] = tree[id << 1];
for (int x : tree[id << 1 | 1]) tree[id].insert(x);
// cout << "RANGE " << l << " " << r << "\n";
// for (int x : tree[id]) cout << x << " ";
// cout << "\n";
}
void update(int pos, int oldVal, int newVal) {
int id = 1, l = 1, r = nNode;
while (true) {
tree[id].erase(tree[id].find(oldVal));
tree[id].insert(newVal);
if (l == r) return;
int mid = (l + r) >> 1;
if (pos <= mid) {
id = id << 1;
r = mid;
}
else {
id = id << 1 | 1;
l = mid + 1;
}
}
}
ii get(int id, int l, int r, int u, int v, int val) {
if (l > v || r < u) return {-1, INF};
if (l >= u && r <= v) {
auto it = tree[id].upper_bound(val);
int larger = (it == tree[id].end() ? INF : (*it));
int smaller = (it == tree[id].begin() ? -1 : (*(--it)));
return make_pair(smaller, larger);
}
int mid = (l + r) >> 1;
ii A = get(id << 1, l, mid, u, v, val);
ii B = get(id << 1 | 1, mid + 1, r, u, v, val);
return make_pair(max(A.F, B.F), min(A.S, B.S));
}
ii get(int l, int r, int val) {
if (l > r) return make_pair(-1, INF);
return get(1, 1, nNode, l, r, val);
}
} magic;
void dfs(int u, int p) {
in[u] = ++timer;
node[in[u]] = u;
sz[u] = 1;
for (int v : adj[u]) if (v != p)
dfs(v, u), sz[u] += sz[v];
out[u] = timer;
}
int ans = INF;
int calc(int x, int y, int z) {
return max({x, y, z}) - min({x, y, z});
}
void reroot(int u, int p, int oldSize) {
if (u != 1 && (nNode - oldSize) / 2 >= oldSize) {
ii a = magic.get(1, in[u] - 1, (nNode - oldSize) / 2);
ii b = magic.get(out[u] + 1, nNode, (nNode - oldSize) / 2);
// cout << "NODE " << u << " " << oldSize << ":\n";
// cout << 1 << " " << in[u] - 1 << ": " << a.F << ", " << a.S << "\n";
// cout << out[u] + 1 << " " << nNode << ": " << b.F << ", " << b.S << "\n";
int x = max(a.F, b.F), y = min(a.S, b.S);
minimize(ans, calc(oldSize, x, nNode - x - oldSize));
minimize(ans, calc(oldSize, y, nNode - y - oldSize));
// cout << "ANS: " << ans << "\n";
}
for (int v : adj[u]) if (v != p) {
int oldU = sz[u], oldV = sz[v];
sz[u] -= sz[v];
sz[v] = nNode;
magic.update(in[u], oldU, sz[u]);
magic.update(in[v], oldV, sz[v]);
reroot(v, u, oldV);
magic.update(in[u], sz[u], oldU);
magic.update(in[v], sz[v], oldV);
sz[u] = oldU;
sz[v] = oldV;
}
}
void solve() {
cin >> nNode;
FOR(i, 1, nNode - 1) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs(1, -1);
magic.build(1, 1, nNode);
reroot(1, -1, 0);
cout << ans;
}
int32_t main() {
if (fopen(task".inp", "r")) {
freopen(task".inp", "r", stdin);
freopen(task".out", "w", stdout);
}
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
bool multitest = 0;
int numTest = 1;
if (multitest) cin >> numTest;
while (numTest--) {
solve();
}
return 0;
}
/* Lak lu theo dieu nhac!!!! */
컴파일 시 표준 에러 (stderr) 메시지
papricice.cpp: In function 'int32_t main()':
papricice.cpp:158:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
158 | freopen(task".inp", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
papricice.cpp:159:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
159 | freopen(task".out", "w", stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |