题意:给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和
板子题
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; const int maxn = 100000 + 10 ; struct Node { int to,next; }edge[maxn * 2]; int head[maxn * 2],tot; void add(int x,int y) { edge[++tot].to = y; edge[tot].next = head[x]; head[x] = tot; } long long n,col[maxn],siz[maxn],ans[maxn],son[maxn]; void dfs1(int u,int fa) { siz[u]=1; for(int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(v==fa) continue; dfs1(v,u); siz[u]+=siz[v]; if(siz[v]>siz[son[u]]) son[u]=v; } } long long cnt[maxn],maxx,sum,Son; void add(int u,int fa,int val) { cnt[col[u]]+=val; if(cnt[col[u]] > maxx) maxx = cnt[col[u]] , sum = col[u]; else if(cnt[col[u]] == maxx) sum+=col[u]; for(int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(v==fa || v == Son) continue; add(v,u,val); } } void dfs2(int u,int fa,int xp) { for(int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(v==fa) continue; if(v!=son[u]) dfs2(v,u,0); } if(son[u]) dfs2(son[u],u,1),Son = son[u]; add(u,fa,1); Son = 0; ans[u]=sum; if(!xp) add(u,fa,-1) , sum = 0 , maxx = 0 ; } int main() { cin>>n; for(int i=1;i<=n;i++) scanf("%lld",&col[i]); for(int i=1,x,y;i<n;i++) { scanf("%d%d",&x,&y); add(x,y);add(y,x); } dfs1(1,0); dfs2(1,0,0); for(int i=1;i<=n;i++) printf("%lld ",ans[i]); return 0; }