思路就是尽量连相距远的叶节点,然后如果有落单的叶节点就把这个叶节点连到根上,为什么有的点没过?
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
const int N = 5e5+5;
int n;
int tot = 0 , head[N];
int dfn[N] , sz[N] , idx = 0 , dep[N] , dp;
struct edge{
int to , nxt;
}e[N*2];
struct leaf{
int id , val;
}lf[N];
void add( int u , int v ){
e[++tot].to = v;
e[tot].nxt = head[u];
head[u] = tot;
}
void dfs( int u , int fa ){
//sz[u] = 1;
dfn[u] = ++idx;
dep[u] = dep[fa] + 1;
for( int i = head[u] ; i ; i = e[i].nxt ){
int v = e[i].to;
if( v == fa ) continue;
dfs( v , u );
//sz[u] += sz[v];
}
}
bool cmp( leaf a , leaf b ){
return a.val < b.val;
}
int main( ) {
cin >> n;
for( int i = 1 , a , b ; i < n ; i++ ){
cin >> a >> b;
add( a , b );
add( b , a );
sz[a]++;
sz[b]++;
}
//dep[1] = 1;
dfs( 1 , 0 );
int ans = 0;
for( int i = 1 ; i <= n ; i++ ){
if( sz[i] == 1 ){
lf[++ans].id = i;
lf[ans].val = dfn[i];
}
dp = max( dp , dep[i] );
}
sort( lf + 1 , lf + ans + 1 , cmp );
cout << ans-ans/2 <<endl;
int l = 1 , r = ans;
while( l < r ){
if( lf[l].id > lf[r].id ) swap( lf[l].id , lf[r].id );
cout << lf[l].id << " " << lf[r].id <<endl;
l++;
r--;
}
if( ans&1 ){
if( dp > 2 ) cout << 1 <<" "<< lf[l].id <<endl;
else cout << lf[l-1].id <<" "<< lf[r].id <<endl;
}
return 0;
}