#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <stdlib.h> #include <sstream> #include <map> #include <set> typedef long long ll; using namespace std; const int N=100005; int dep[N],siz[N],fa[N],son[N]; //dfs1求出每个节点的深度、大小、父亲节点、重儿子节点 int n; int vis[N],num[N],top; ll c[N],sum[N],ans[N]; struct node { int v; //边的终点 //如果边有权值的话,加上int w;代表边的权值 int nex; }e[N<<1]; int first[N],tot; //first数组是链式向前星的前一个数组 void init() //初始化 { tot=0; //tot是链式向前星记录边个数的变量 top=0; memset(first,-1,sizeof(first)); //链式向前星的first数组一般设为-1 } void adde(int u,int v) { e[tot].v=v; e[tot].nex=first[u]; first[u]=tot++; } void dfs1(int u,int pre,int depth) //从根节点1开始,上一个节点是0,深度是1,最后标记每一个节点的dep(深度),fa(父亲节点),siz(大小),son(重儿子节点) { dep[u]=depth; fa[u]=pre; siz[u]=1; for(int i=first[u];i!=-1;i=e[i].nex) //遍历u节点的儿子节点 { int v=e[i].v; //这条边的终点 if(v==pre) continue; //如果终点等于他的父亲节点就continue; dfs1(v,u,depth+1); //节点变为这条边的终点,父亲节点是u节点,每次的深度+1 /*一直dfs,直到到达叶子节点,然后从下到上更新每个节点的size数组*/ if(siz[son[u]]<siz[v]) son[u]=v;//如果现在重儿子的大小 < 当前终点节点的大小,更新重儿子为v siz[u]+=siz[v]; //u的大小都要加上终点的大小 } } void update(int u,int pre,int t) { sum[num[c[u]]]-=c[u]; num[c[u]]+=t; sum[num[c[u]]]+=c[u]; if(sum[top+1]) top++; if(!sum[top]) top--; for(int i=first[u];~i;i=e[i].nex) { int v=e[i].v; if(v==pre||vis[v]) continue; update(v,u,t); //合并没被保留下来的子节点 } } void dfs2(int u,int pre,int so) //从根节点1,父亲节点0,so是1开始 { for(int i=first[u];i!=-1;i=e[i].nex) //遍历与u相连的点 { int v=e[i].v; if(v==pre||v==son[u]) continue; //如果是父节点或者是重儿子(意思就是:如果是父亲节点本来就不算,如果是重儿子节点,就先跳过) dfs2(v,u,0); //如果u的儿子节点v 是u的轻儿子节点 } if(son[u]) //最后遍历重儿子 { dfs2(son[u],u,1); vis[son[u]]=1; //标记保留下来的节点 } update(u,pre,1); vis[son[u]]=0; ans[u]=sum[top]; //记录答案 if(so==0) update(u,pre,-1); //如果不是重节点清除数组 } int main() { scanf("%d",&n); init(); for(int i=1;i<=n;i++) scanf("%lld",&c[i]); int u,v; for(int i=1;i<n;i++) { scanf("%d%d",&u,&v); /*添加双向边*/ adde(u,v); adde(v,u); } dfs1(1,0,1); dfs2(1,0,1); for(int i=1;i<=n;i++) printf("%lld ",ans[i]); printf("\n"); return 0; }