ツリーツリーDPの深さ

タイトルの説明

 

 入力

 

 アウトプット

 

 サンプル

入力例

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、-1sizeof (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(10 ;)
 53は      DFS2(10 );
 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 }
コードを表示

 

おすすめ

転載: www.cnblogs.com/liuchanglc/p/12686626.html