cf 686D - Kay and Snowflake
Posted shatianming
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cf 686D - Kay and Snowflake相关的知识,希望对你有一定的参考价值。
题意让你求每个子树的重心
直接求肯定不行对吧......然后又是在树上
考虑树的重心的性质
1.任意一个子树小于当前树的二分之一 (换句话 一棵树的重心一定是自己或者是重儿子子树上)
2.当两个子树连接的时候新接成的树的重心一定在 两个子树重心的路径上
然后发现.....这个题 可以直接分治 跑 然后就没了
嘛....主要我不会写....(就是那种似懂非懂.....原理知道,但不会操作的感觉....)
关键就在于合并.,,,
只要递归搞到子树的重心....然后逐步往上跳 直至满足与当前树合并为重心.....
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define MAXN 300005 using namespace std; int n,q,tot; int h[MAXN],ans[MAXN],f[MAXN],sz[MAXN];//以u为根的子树的重心 各点父亲 子树大小 struct node{ int from,to,next; }e[MAXN<<1]; void init(){ memset(h,-1,sizeof(h)); memset(sz,0,sizeof(sz)); } void add(int x,int y){ tot++; e[tot].from=x; e[tot].to=y; e[tot].next=h[x]; h[x]=tot; } int dfs(int now,int fa){ f[now]=fa; sz[now]=1; ans[now]=now; for(int i=h[now];i!=(-1);i=e[i].next){ if(e[i].to!=fa){ dfs(e[i].to,now); sz[now]+=sz[e[i].to]; } } for(int i=h[now];i!=(-1);i=e[i].next){ if(e[i].to!=fa&&sz[e[i].to]*2>sz[now]){ ans[now]=ans[e[i].to]; } } while((sz[now]-sz[ans[now]])*2>sz[now]){ ans[now]=f[ans[now]]; } } int main(){ cin>>n>>q;init(); for(int i=2;i<=n;i++){ int p;cin>>p; add(i,p); add(p,i); } dfs(1,1); for(int i=1;i<=q;i++){ int p;cin>>p; cout<<ans[p]<<endl; } }
以上是关于cf 686D - Kay and Snowflake的主要内容,如果未能解决你的问题,请参考以下文章
Kay and Snowflake CodeForces - 685B (重心, 好题)
CodeForces 685B Kay and Snowflake
Codeforces 686 D - Kay and Snowflake
codeforces 685B Kay and Snowflake 树的重心