190710-freedom-长链剖分
作者:互联网
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
deg[i]==1代表链最底端,此时deep[i]-deep[tp[i]]=链的长度。
长链剖分:
deep是深度,fa是父亲节点,h子树最大深度
son是重儿子,tp是这条重链深度最小的点,也就是重链的顶点。
标签:190710,剖分,int,freedom,tp,son,fa,deep,include 来源: https://www.cnblogs.com/Moxingtianxia/p/11686506.html