思路:
考慮往直徑方向想,設直徑的長度為 \(d\)。
首先可以注意到一個性質:
- 每次操作最多隻會覆蓋住直徑的 \(2\) 個點,那麼答案的下界即為 \(\lceil \frac{d}{2} \rceil\)。
分類討論一下。
若 \(d\) 為奇數,則存在唯一的一個直徑中心 \(u\):
-
那麼答案為 \((u,0),(u,1),\cdots,(u,\lceil \frac{d-1}{2} \rceil)\)。
-
最優次數是 \(\lceil \frac{d}{2} \rceil\) 次。
若 \(d\) 為偶數,則存在兩個直徑中心 \(u,v\):
-
若 \(d \bmod 4 = 0\) 時:
-
那麼答案為 \((u,1),(v,1),(u,3),(v,3),\cdots,(u,\frac{d}{2}-1),(v,\frac{d}{2}-1)\)。
-
最優次數是 \(\frac{d}{2}\)。
-
這樣是兩者是完全錯開的。
-
-
若 \(d \bmod 4 = 2\) 時:
-
那麼答案為 \((u,0),(u,1),\cdots,(u,\frac{2}{d})\)。
-
最優次數是 \(\frac{d}{2}+1\)。
-
這裡證明一下為什麼當 \(d \bmod 4 = 0\) 時不能取到答案的下界。
注意到若 \(x,y\) 能被同時取到當且僅當 \(\operatorname{dis}(x,y)\) 為偶數。
設 \(L\) 為直徑的一個端點,那麼 \(\operatorname{dis}(L,x)+\operatorname{dis}(L,y)\) 的奇偶性等價於 \(2*(奇數/偶數)+偶數=偶數\)。
因為 \(d \bmod 4 = 2\),所以 \(\sum \operatorname{dis}(L,i) = \frac{d \times (d-1)}{2} \bmod 4 = 1\),則這個和式一定不是偶數,故無法達到下界。
時間複雜度為 \(O(TN)\)。
完整程式碼:
#include<bits/stdc++.h>
#define Add(x,y) (x+y>=mod)?(x+y-mod):(x+y)
#define lowbit(x) x&(-x)
#define pi pair<ll,ll>
#define pii pair<ll,pair<ll,ll>>
#define iip pair<pair<ll,ll>,ll>
#define ppii pair<pair<ll,ll>,pair<ll,ll>>
#define fi first
#define se second
#define full(l,r,x) for(auto it=l;it!=r;it++) (*it)=x
#define Full(a) memset(a,0,sizeof(a))
#define open(s1,s2) freopen(s1,"r",stdin),freopen(s2,"w",stdout);
using namespace std;
typedef double db;
typedef unsigned long long ull;
typedef long long ll;
bool Begin;
const ll N=2e3+10;
inline ll read(){
ll x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')
f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=(x<<1)+(x<<3)+(c^48);
c=getchar();
}
return x*f;
}
inline void write(ll x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
write(x/10);
putchar(x%10+'0');
}
ll T,n,x,y,id,sum,cnt;
ll a[N],d[N],fa[N];
vector<ll> E[N];
void add(ll u,ll v){
E[u].push_back(v);
E[v].push_back(u);
}
void dfs(ll u,ll f){
for(auto v:E[u]){
if(v==f)
continue;
fa[v]=u;
d[v]=d[u]+1;
dfs(v,u);
}
}
void solve(){
cnt=0;
n=read();
for(int u,v,i=1;i<n;i++){
u=read(),v=read();
add(u,v);
}
fa[1]=d[1]=sum=0;
dfs(1,1);
for(int i=1;i<=n;i++){
if(d[i]>=sum){
sum=d[i];
id=i;
}
}
//cerr<<id<<'\n';
fa[id]=d[id]=sum=0;
dfs(id,id);
for(int i=1;i<=n;i++){
if(d[i]>=sum){
sum=d[i];
id=i;
}
// cerr<<d[i]<<' ';
}
// cerr<<'\n';
while(id){
a[++cnt]=id;
id=fa[id];
}
if(cnt&1ll){
x=a[(cnt+1)>>1ll];
write((cnt+1)>>1ll);
putchar('\n');
for(int i=0;i<((cnt+1)>>1ll);i++){
write(x);
putchar(' ');
write(i);
putchar('\n');
}
}
else{
x=a[cnt>>1ll],y=a[(cnt>>1ll)+1];
if(cnt&3ll){
write((cnt>>1ll)+1);
putchar('\n');
for(int i=0;i<=(cnt>>1ll);i++){
write(x);
putchar(' ');
write(i);
putchar('\n');
}
}
else{
write(cnt>>1ll);
putchar('\n');
for(int i=1;i<(cnt>>1ll);i+=2){
write(x);
putchar(' ');
write(i);
putchar('\n');
write(y);
putchar(' ');
write(i);
putchar('\n');
}
}
}
for(int i=1;i<=n;i++)
E[i].clear();
}
bool End;
int main(){
T=read();
while(T--)
solve();
cerr<<'\n'<<abs(&Begin-&End)/1048576<<"MB";
return 0;
}