1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
| #include <bits/stdc++.h> using namespace std; using ll = long long;
const int maxn = 3e5 + 50; const int maxlg = 20;
struct Edge { int u, v; };
vector< int > adj[maxn]; int sz[maxn], f[maxn]; int son1[maxn], son2[maxn]; int down[maxn][maxlg], fa[maxn]; int bel[maxn]; int n, rt; ll ans;
void get_root( int u, int p ) { sz[u] = 1; f[u] = 0;
for( int v : adj[u] ) { if( v == p ) continue; get_root( v, u ); sz[u] += sz[v]; f[u] = max( f[u], sz[v] ); }
f[u] = max( f[u], n - sz[u] ); if( f[u] < f[rt] ) rt = u; }
void dfs( int u, int p, int top ) { sz[u] = 1; fa[u] = p; bel[u] = top; son1[u] = son2[u] = 0;
for( int v : adj[u] ) { if( v == p ) continue;
if( u == rt ) dfs( v, u, v ); else dfs( v, u, top ); sz[u] += sz[v];
if( sz[v] > sz[son1[u]] ) son2[u] = son1[u], son1[u] = v; else if( sz[v] > sz[son2[u]] ) son2[u] = v; } down[u][0] = son1[u]; for( int i = 1; i < maxlg; ++ i ) down[u][i] = down[down[u][i - 1]][i - 1]; }
int check( int u, int sum, int ms ) { return u * ( max( ms, sum - sz[u] ) <= sum / 2 ); }
void calc( int st, int sum, int del ) {
int son = son1[st]; if( st == rt && son1[st] == del ) son = son2[st];
ans += check( st, sum, sz[son] ); if( son == 0 || sz[son] < ( sum + 1 ) / 2 ) return;
int cur = son; for( int i = maxlg - 1; i >= 0; -- i ) { int nxt = down[cur][i]; if( nxt && sz[nxt] >= ( sum + 1 ) / 2 ) cur = nxt; } ans += check( cur, sum, sz[son1[cur]] ); if( cur != son ) ans += check( fa[cur], sum, sz[son1[fa[cur]]] ); }
void solve( ) { cin >> n;
ans = 0; for( int i = 1; i <= n; ++ i ) adj[i].clear( );
vector< Edge > edges; for( int i = 1; i < n; ++ i ) { int u, v; cin >> u >> v; adj[u].push_back( v ); adj[v].push_back( u ); edges.push_back( { u, v } ); }
rt = 0; f[0] = n + 1; get_root( 1, 0 ); dfs( rt, 0, 0 );
for( auto [u, v] : edges ) { if( fa[v] != u ) swap( u, v ); calc( v, sz[v] , 0 ); calc( rt, n - sz[v], bel[v] ); }
cout << ans << '\n'; }
int main( ) { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int T; cin >> T; while( T -- ) solve( ); return 0; }
|