190710-freedom-长链剖分

≯℡__Kan透↙ 提交于 2019-12-01 12:44:04
 1 #include<iostream>
 2 #include<cmath>
 3 #include<cstdio>
 4 #include<string>
 5 #include<cstring>
 6 #include<algorithm>
 7 using namespace std;
 8 namespace Moxing{
 9     const int N=1000050;
10     struct node{
11         int to,nxt;
12     }edge[N<<1];
13     int n,last[N],cnt,deg[N],ans[N],m;
14     void add(int from,int to){
15         edge[++cnt].to=to,edge[cnt].nxt=last[from],last[from]=cnt;
16         deg[to]++;
17     } 
18     //deep是深度,fa是父亲节点,h子树最大深度 
19     //son是重儿子,tp是这条重链深度最小的点,也就是重链的顶点。
20     int deep[N],h[N],son[N],tp[N];
21     void dfs1(int x,int fa){
22         deep[x]=deep[fa]+1;
23         for(int i=last[x];i;i=edge[i].nxt){
24             int y=edge[i].to;
25             if(y==fa) continue ;
26             dfs1(y,x);
27             if(h[y]>h[son[x]]) son[x]=y;
28         }
29         h[x]=h[son[x]]+1;
30     }
31     void dfs2(int x,int fa){
32         if(son[x]){
33             tp[son[x]]=tp[x];
34             dfs2(son[x],x);
35         }
36         for(int i=last[x];i;i=edge[i].nxt){
37             int y=edge[i].to;
38             if(y==fa||y==son[x]) continue ;
39             tp[y]=y;dfs2(y,x);
40         }
41     }
42     struct main{
43         main(){
44             scanf("%d",&n);
45             for(int i=1;i<=n-1;i++){
46                 int x,y;
47                 scanf("%d%d",&x,&y);
48                 add(x,y),add(y,x);
49             } 
50             dfs1(1,0),tp[1]=1,dfs2(1,0);
51             for(int i=1;i<=n;i++){
52                 if(deg[i]==1&&i!=1){
53                     ans[++m]=deep[i]-deep[tp[i]]+1;
54                 }
55             }
56             sort(ans+1,ans+m+1);
57             ans[m]--;
58             printf("%d\n",m);
59             for(int i=m;i;i--){
60                 ans[i]+=ans[i+1];
61                 printf("%d\n",ans[i]);
62             }
63             exit(0);
64         }
65     }UniversalLove;
66 }
67 int main(){
68     Moxing::main();
69 }
View Code

长链剖分:

deep是深度,fa是父亲节点,h子树最大深度
son是重儿子,tp是这条重链深度最小的点,也就是重链的顶点。

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!