# Codeforces Round #720 (Div. 2) D. Nastia Plays with a Tree

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100005;
#define pb push_back

int f[N][3],n,t,to[N][3],min_pos[N],p[N],ccnt,Side[N][2],color[N],get_fa[N];
vector<int> g[N];
bool ban[N];

inline void init(int x){
for(int i=1;i<=x;i++) g[i].clear(),ban[i] = to[i][0] = to[i][1] = to[i][2] = 0;
for(;ccnt;ccnt--) Side[ccnt][0] = Side[ccnt][1] = 0;
}

int get_pa(int x){ return get_fa[x] == x?x:(get_fa[x] = get_pa(get_fa[x]));}

void dfs(int x,int fa){
p[x] = fa;

int base = 0,MIN = 1e8,MIN_ADD_SECMIN = 1e9,son = 0;
int son_min,son_amin,derta,son_amin_from;

for(int s:g[x]) if(s!=fa){
dfs(s,x),son++;

son_amin = min(f[s][0],f[s][1]);
son_amin_from = f[s][0]<f[s][1] ? 0 : 1;
son_min = min(son_amin,f[s][2]);
derta = son_amin - son_min;

base += son_min;
if(derta <= MIN) to[x][2] = to[x][0],to[x][0] = (n+1) * son_amin_from + s;
else to[x][2] = (n+1) * son_amin_from + s;
}
if(derta < MIN) MIN = derta,to[x][1] = (n+1) * son_amin_from + s;
}

f[x][0] = base + son;
f[x][1] = base + MIN + son - 1;
f[x][2] = base + MIN_ADD_SECMIN + son - 2;

min_pos[x] = 0;
if(f[x][1] < f[x][min_pos[x]]) min_pos[x] = 1;
if(f[x][2] < f[x][min_pos[x]]) min_pos[x] = 2;
}

void dfss(int x,int type,const int &ha){
//printf("%d %d\n",x,type);
if(type < 0) type = min_pos[x],ban[x] = 1;
for(int s:g[x]) if(s!=p[x]){
if(type == 1 && to[x][1] % ha == s) dfss(s,to[x][1] / ha,ha);
else if(type == 2){
if(to[x][0] % ha == s) dfss(s,to[x][0] / ha,ha);
else if(to[x][2] % ha == s) dfss(s,to[x][2] / ha,ha);
else dfss(s,-1,ha);
}
else dfss(s,-1,ha);
}
}

void dfsss(int x){
color[x] = ccnt;
int newson = 0;
for(int s:g[x]) if(s!=p[x] && !ban[s])
dfsss(s),newson++;
if(newson == 0)
if(!Side[ccnt][1]) Side[ccnt][1] = x;
else Side[ccnt][0] = Side[ccnt][1],Side[ccnt][1] = x;
}

inline void output(){
printf("%d\n",min(f[1][0],min(f[1][1],f[1][2])));
for(int i=2,fa,fb;i<=n;i++) if(ban[i]){
fa = get_pa(color[i]),fb = get_pa(color[p[i]]);
printf("%d %d %d %d\n",i,p[i],Side[fa][0],Side[fb][1]);
get_fa[fb] = fa,Side[fa][0] = Side[fb][0];
}
}

int main(){
for(scanf("%d",&t);t--;){
init(n),scanf("%d",&n);
for(int u,v,i=1;i<n;i++)
scanf("%d%d",&u,&v),g[u].pb(v),g[v].pb(u);

dfs(1,0);
const int ha = n+1;
dfss(1,-1,ha);
for(int i=1;i<=n;i++) if(ban[i]) ccnt++,Side[ccnt][0] = i,dfsss(i);
for(int i=1;i<=ccnt;i++) get_fa[i] = i,Side[i][1] = Side[i][1] == 0 ? Side[i][0]:Side[i][1];
output();
}

return 0;
}


posted @ 2021-05-16 23:32  蒟蒻JHY  阅读(36)  评论(0编辑  收藏  举报