Topic: https://vjudge.net/contest/307753#problem/D
Meaning of the questions: to give you a tree, so that you find a spot to get his biggest sub-tree nodes as small as possible
Ideas: the largest sub-tree nodes as small as possible, a look that is the center of gravity of the tree, and then casually set a point in the original partition template can
#include <cstdio> #include <CString> #include <the cmath> #include <algorithm> #include <the iostream> #include <Vector> #define MAXN 100005 #define MOD 1E19 the using namespace STD; typedef Long Long LL; LL DA; Vector <pair <LL, LL>> MP [MAXN]; // save enough FIG BOOL VIS [MAXN]; // tag have used gravity LL MAXSIZE [MAXN], DIS [MAXN], D [MAXN]; / / largest subtree of the current node maxsize LL SIZ [MAXN], E [MAXN]; // DIS distance to the center of gravity d distance appeared n-LL, m, rt, SUM, QE; // distance e siz number subtree of the current node appears rt represents the current focus void Find (X LL, LL F) { // find the center of gravity SIZ [X] = . 1 ; MAXSIZE [X] = 0 ; for ( int I = 0 ; I <MP [X] .size (); I ++ ) { pair <LL, LL> Q = MP [X] [I]; IF (q.first || F VIS == [q.first]) Continue ; // VIS array tags have used gravity Find (q.first, X); SIZ [X] + = SIZ [q.first]; MAXSIZE [X] = max (MAXSIZE [X], SIZ [q.first]); } MAXSIZE [X] = max (MAXSIZE [X], SUM-SIZ [X]); // total number of nodes by subtracting the current number = subtree rooted at the current node number father idea tree IF (MAXSIZE [X] < MAXSIZE [RT]) { RT = X; } the else IF (MAXSIZE [X] == MAXSIZE [RT] && RT> X) { RT = X; } } void get_dis (LL X, LL F, LL len) { E [ + QE +] = len; for ( int I = 0 ; I <MP [X] .size (); I ++ ) { pair <LL, LL> Q = MP [X] [I]; IF (== q.first VIS || F [q.first]) Continue ; dis[q.first]=dis[x]+len; get_dis(q.first,x,len+q.second); } } ll solve(ll x,ll len){ ll ee=0; qe=0; dis[x]=len; get_dis(x,0,len); sort(e+1,e+qe+1); ll l=1,r=qe; while(l<r){ if(e[l]+e[r]<=m){ ee+=r-l; l++; } else{ r--; } } return ee; } void divide(ll x){ da+=solve(x,0); vis[x]=1; for(int i=0;i<mp[x].size();i++){ pair<ll,ll> q=mp[x][i]; if(vis[q.first]) continue; da-=solve(q.first,q.second); sum=siz[q.first]; rt=0; maxsize[rt]=mod; find(q.first,x); divide(rt); } } void init(){ da=0; for(int i=0;i<=n;i++) mp[i].clear(); for(int i=0;i<=n;i++) vis[i]=0; } int main(){ int t; scanf("%d",&t); while(t--) { scanf("%lld",&n); ll a,b,c; init(); for(int i=0;i<n-1;i++){ scanf("%lld%lld",&a,&b); mp[a].push_back(make_pair(b,c)); mp[b].push_back(make_pair(a,c)); } sum=n;//当前节点数 rt=0; maxsize[0]=mod;//置初值 find(1,0); //divide(rt); printf("%lld %lld\n",rt,maxsize[rt]); } }