This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int, int> pi;
#define debug(x) cerr << #x << ": " << x << endl
#define debug2(x, y) debug(x), debug(y)
#define repn(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i, a) for(int i = 0; i < (int)(a); i++)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define sq(x) ((x) * (x))
const int mxN = 1e5 + 5;
template<class T> T gcd(T a, T b){ return ((b == 0) ? a : gcd(b, a % b)); }
vi g[mxN];
int ch[mxN], p[mxN], repr[mxN], vis[mxN], cnt1[mxN];
int mx = 0, bst = -1;
int mx1 = 0, bst1 = -1;
void dfs(int cur, int prev, int d){
if(d > mx){
mx = d;
bst = cur;
}
for(int x : g[cur]) if(x != prev) dfs(x, cur, d + 1);
}
void dfs1(int cur, int prev, int d){
if(d > mx1){
mx1 = d;
bst1 = cur;
}
p[cur] = prev;
for(int x : g[cur]) if(x != prev) dfs1(x, cur, d + 1);
}
vi fishyOrz[mxN];
void dfs2(int cur, int prev, int lst){
int cnt = 0;
if(ch[cur]) lst = cur;
for(int x : g[cur]) if(x != prev) dfs2(x, cur, lst), cnt++;
if(!cnt && !ch[cur]){
assert(lst != -1);
repr[lst] = cur;
cnt1[lst]++;
fishyOrz[lst].pb(cur);
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
//freopen("input.in", "r", stdin);
//freopen("output.out", "w", stdout);
int n;
cin >> n;
rep(i, n - 1){
int a, b;
cin >> a >> b;
a--, b--;
g[a].pb(b);
g[b].pb(a);
}
dfs(0, -1, 0);
assert(bst != -1);
dfs1(bst, -1, 0);
assert(bst1 != -1);
int nw = bst1;
while(nw != -1){
ch[nw] = 1;
nw = p[nw];
}
dfs2(bst, -1, -1);
vector<pi> ans;
set<pi> st;
rep(i, mxN) if(fishyOrz[i].size()){
st.insert({(int)fishyOrz[i].size(), i});
}
int st1 = -1;
int f = 1;
while(st.size()){
if(st.size() > 1){
pi cur = *(--st.end());
pi cur1 = *prev(--st.end());
st.erase(--st.end());
st.erase(--st.end());
ans.pb({fishyOrz[cur.se].back(), fishyOrz[cur1.se].back()});
fishyOrz[cur.se].pop_back();
fishyOrz[cur1.se].pop_back();
if(cur.fi > 1) st.insert({cur.fi - 1, cur.se});
if(cur1.fi > 1) st.insert({cur1.fi - 1, cur1.se});
}
else{
pi cur = *st.begin();
for(int i = 0; i < (cur.fi - 1); i += 2){
ans.pb({fishyOrz[cur.se][i], fishyOrz[cur.se][i + 1]});
}
st1 = cur.se;
if(cur.fi & 1){
int nd = -1;
for(int x : g[cur.se]) if(ch[x]) nd = x;
assert(nd != -1);
ans.pb({fishyOrz[cur.se][cur.fi - 1], nd});
f = 0;
}
break;
}
}
repn(i, st1, st1 + 1) if(st1 != -1){
int nd = -1;
int nm1 = 0;
for(int x : g[i]) if(!ch[x]) nd = x, nm1++;
int nd1 = -1;
for(int x : g[i]) if(ch[x]) nd1 = x;
if(ch[i] && (nd != -1) && !vis[i] && (nd1 != -1) && cnt1[i] % 2 == 0 && nm1 == 1 && f) ans.pb({repr[i], nd1});
}
ans.pb({bst, bst1});
cout << (int)ans.size() << '\n';
for(pi x : ans) cout << x.fi + 1 << " " << x.se + 1 << '\n';
return 0;
}
/*
Things to look out for:
- Integer overflows
- Array bounds
- Special cases
Be careful!
*/
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |