ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

还是DFS——new_bzoj Sta

2020-04-12 17:01:09  阅读:191  来源: 互联网

标签:子树 Sta int long 父树 DFS new include


题目链接: https://vijos.org/d/newbzoj/p/590c9893d3d8a132109937a3

其实题意很简单,先看一下:给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大

如果暴力的话必然是会TLE的。

所以我们必须想办法。

我记得有一道题是把n次DFS优化为了2次DFS

这道题是不是也可以呢?

我们可以想想。

答案是可以的。

看一下思路:

首先所有点等于父树的点+子树的点。

那么只要求出这两者累加就好了;

子树的总深度简直好求,就是将儿子的总深度+size就好了;

父树的稍微有点麻烦,因为需要一些预处理所以在第二次深搜解决;

对于一个点来说,这个点的父树就是【父亲+父亲的父树+兄弟的子树】;

那么分别累加即可:
注意一下推公式就好;

时间复杂度O(n)
不过有几个细节问题:

1.公式 一定要算好(加减同一项不要消下去。。不然没法调。。)

2.此题需要long long 

后面是代码。

加了一些注释。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 const int maxn=1000005;
 6 using namespace std;
 7 typedef long long ll;
 8 int n,no,to[maxn<<1],next[maxn<<1],head[maxn],cnt;
 9 ll sum[maxn],size[maxn],fas[maxn],ans;
10 void add(int x,int y){
11     to[++cnt]=y;next[cnt]=head[x];head[x]=cnt;
12 }
13 void DFS1(int x,int pre){
14     size[x]=1;int i,y;//size是子树的大小 ,包括x 
15     for(i=head[x];i;i=next[i]){
16         if((y=to[i])!=pre){
17             DFS1(y,x);
18             size[x]+=size[y];
19             sum[x]+=sum[y]+size[y];//sum是深度和,但是不包括x 
20         }
21     }
22 }
23 void DFS2(int x,int pre){
24     int i,y;
25     if(x!=1)fas[x]=fas[pre]+n-size[pre]+sum[pre]-sum[x]-size[x]+size[pre]-size[x]-1+1;
26     //fas[pre]+n-size[pre]是第一部分
27     //sum[pre]-sum[x]-size[x]+size[pre]-size[x]-1 是第二部分
28     //1 是第三部分 
29     //公式要好好理解 
30     if(ans<fas[x]+sum[x]){//fas是父树和 
31         ans=fas[x]+sum[x]; 
32         no=x;
33     }
34     else if(ans==fas[x]+sum[x])no=min(no,x);
35     for(i=head[x];i;i=next[i]){
36         if((y=to[i])!=pre){
37             DFS2(y,x);
38         }
39     }
40 }
41 int main(){
42     //freopen("a.in","r",stdin);
43     scanf("%d",&n);
44     for(int i=1;i<n;i++){
45         int x,y; scanf("%d%d",&x,&y);
46         add(x,y);add(y,x);
47     }
48     DFS1(1,0);DFS2(1,0);
49     printf("%d\n",no);
50     return 0;
51 }

 

标签:子树,Sta,int,long,父树,DFS,new,include
来源: https://www.cnblogs.com/DZN2004/p/12686227.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有