タイトルの説明
入力
アウトプット
サンプル
入力例
8 1 4 5 6 4 5 6 7 6 8 2 4 3 4
出力例
7
分析
この質問のデータは1000000です。すべての頂点を一度列挙することは明らかに非現実的であり、確実に削除されます。
したがって、写真からパターンを探します
習慣に従って、最初にノード1をルートノードとしてシミュレートします
ノード1を1つのdfsを介してルートノードとして使用すると、ツリーの深さを簡単に合計できます。
1 + 2 * 3 + 3 + 4 * 2 = 18(もちろん、ルートノードの深さを1に設定しても結果には影響しません)
次に、ルートノードを4つの適切なノードに移動します。
ルートノードとして1を使用する場合と比較すると、ノード1の深さは1増加しますが、4が配置されているサブツリーのノードの深さは1減少します。
同様に、この時点でルートノードを5に下げます。ルートノードとして4を使用する場合と比較すると、ノード1、4、3、および2の深さは1ずつ増加しますが、5が配置されているサブツリーのノードの深さは1削減
したがって、iがルートノードの場合、ツリーの次数の合計としてans [i]を設定し、iを持つルートサブツリーのサイズとしてsiz [i]を設定します。
Nàmeans [i] = ans [fa] + n-siz [i] + siz [i] = ans [fa] + n-2 * siz [i]
siz配列を前処理でき、ans [1]からans [fa]も見つけることができるため、この問題は簡単に解決されます
コード
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <cmath> 6 名前空間std を使用 。 7 const int maxn = 2000010 ; 8 typedef long long ll; 9 struct asd { 10 ll from 、to、next; 11 } b [maxn]; 12 ll head [maxn]、tot = 1 、n; 13 void ad(ll aa、ll bb){ 14 b [tot]。 から = aa; 15 b [tot] .to = bb; 16 b [tot] .next = head [aa]; 17 head [aa] = tot ++ ; 18 } 19 ll dep [maxn]、ans [maxn]、siz [maxn]; 20 void dfs(ll now、ll fa){ 21 dep [now] = dep [fa] + 1 ; 22 siz [now] = 1 ; 23 ans [now] = dep [now]; 24 for(ll i = head [now]; i!=- 1 ; i = b [i] .next){ 25 ll u = b [i] .to; 26 if(u == fa)続ける; 27 dfs(u、now); 28 siz [now] + = siz [u]; 29 ans [now] + = ans [u]; 30 } 31 } 32 void dfs2(ll now、ll fa){ 33 for(ll i = head [now]; i!=- 1 ; i = b [i] .next){ 34 ll u = b [i] 。に; 35 であれば(U == FA)続けます。 36 if(u!= 1 ){ 37 ans [u] = ans [now] +(n-siz [u])- siz [u]; 38 } 39 dfs2(u、now); 40 } 41 } 42 int main(){ 43 memset(head、-1、sizeof (head)); 44 scanf(" %lld "、&n); 45 for(ll i = 1 ; i <n; i ++ ){ 46 ll aa、bb; 47 scanf(" %lld%lld "、&aa、&bb); 48 ad(aa、bb); 49 ad(bb、aa); 50 } 51 dep [ 0 ] =-1 ; //ができ、0に設定することができる 52は DFS(1、0 ;) 53は DFS2(1、0 ); 54は、 LL = TOT - 1、JLL = 1 ; 55 用(LL = I 1、I <= n; i ++ ){ 56 if(ans [i]> tot){ 57 tot = ans [i]; 58 jll = i; 59 } 60 } 61 printf(" %lld \ n " 、jll); 62 0を返します。 63 }