文章目录
Rikka with Travels
换根dp
#include <bits/stdc++.h>
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define Pb push_back
#define FI first
#define SE second
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define IOS ios::sync_with_stdio(false)
#define DEBUG cout<<endl<<"DEBUG"<<endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int prime = 999983;
const int INF = 0x7FFFFFFF;
const LL INFF =0x7FFFFFFFFFFFFFFF;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-6;
const LL mod = 1e9 + 7;
LL qpow(LL a,LL b){LL s=1;while(b>0){if(b&1)s=s*a%mod;a=a*a%mod;b>>=1;}return s;}
LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;}
int dr[2][4] = {1,-1,0,0,0,0,-1,1};
typedef pair<int,int> P;
const int maxn = 1e5+10;
int depth[maxn],dp[maxn];
int depth2[maxn],dp2[maxn];
int num[maxn];
vector<int> G[maxn];
void dfs1(int u,int fa){
depth[u] = dp[u] =1;
vector<int> v(2,0);
for(auto c: G[u]){
if(c == fa) continue;
dfs1(c,u);
depth[u] =max(depth[u],depth[c]+1);
dp[u] = max(dp[u],dp[c]);
v.push_back(depth[c]);
}
sort(v.begin(),v.end(),greater<int>());
dp[u] = max(dp[u],v[0]+v[1]+1);
}
void update(int a,int b){
if(a < b) swap(a,b);
num[a] = max(num[a],b);
}
void dfs2(int u,int fa){
P p(0,0);
vector<P> v1(2,p),v2(2,p);
v1.Pb(P(dp2[u],u));
v2.Pb(P(depth2[u]-1,u));
for(auto c:G[u]){
if(c == fa) continue;
v1.Pb(P(dp[c],c));
v2.Pb(P(depth[c],c));
}
// cout<<"Sor"<<endl;
sort(v1.begin(),v1.end(),greater<P>());
sort(v2.begin(),v2.end(),greater<P>());
for(auto c:G[u]){
if(c == fa) continue;
// 求最长链
// cout<<c<<endl;
int &M = dp2[c];
// cout
M = depth2[c] = 0;
// cout<<""
int cnt = 0;
for(int i = 0;i < 3&&cnt<2; ++i){
if(v2[i].second == c)continue;
++cnt;
M += v2[i].first;
depth2[c] = max(depth2[c],v2[i].first+2);
}
M++;
int t =0;
if(v1[t].second==c)++t;
M = max(M,v1[t].first);
update(M,dp[c]);
dfs2(c,u);
}
}
int main(void)
{
int T;cin>>T;
while(T--){
int n;cin>>n;
for(int i = 1;i <=n; ++i)
G[i].clear(),num[i] = 0;
for(int i = 1;i < n;++i){
int u,v;scanf("%d%d",&u,&v);
G[u].Pb(v);
G[v].Pb(u);
}
// cout<<"DF"<<endl;
dfs1(1,-1);
// cout<<dp[1]<<" "<<depth[1]<<endl;
dp2[1] = 1,depth2[1] = 1;
// cout<<"dfs1 end"<<endl;
dfs2(1,-1);
// DEBUG;
LL ans= 0;
LL t=0;
num[n+1] = 0;
for(int i = n;i >= 1; --i){
num[i] = max(num[i],num[i+1]);
ans += min(num[i],i);
if(num[i] >= i)
t++;
// cout<<i<<" "<<num[i]<<endl;
}
cout<<ans*2-t<<endl;
}
return 0;
}
//
/*
dfs1 高度,最长链
dfs2 除这个子树外的最长链
dp[son],depth[son]+depth[son]
2
5
1 2
2 3
3 4
3 5
*/