题目链接:http://codeforces.com/contest/600/problem/E
题意:给你一颗树,找出每个子树下的众数之和;
思路:启发式合并map;
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cmath> #include<string> #include<queue> #include<algorithm> #include<stack> #include<cstring> #include<vector> #include<list> #include<set> #include<map> using namespace std; #define ll long long #define pi (4*atan(1.0)) #define eps 1e-14 #define bug(x) cout<<"bug"<<x<<endl; const int N=1e5+10,M=4e6+10,inf=2147483647; const ll INF=1e18+10,mod=1e9+7; struct is { int v,next; }edge[N<<1]; int head[N],edg; void init() { edg=0; memset(head,-1,sizeof(head)); } void add(int u,int v) { edg++; edge[edg].v=v; edge[edg].next=head[u]; head[u]=edg; } ll ans[N],sum[N]; int a[N]; int maxx[N]; map<int,int>mp[N]; map<int,int>::iterator it; void update(int a,int b) { if(mp[a].size()<mp[b].size()) { swap(maxx[a],maxx[b]); swap(sum[a],sum[b]); swap(mp[a],mp[b]); } while(mp[b].size()) { it=mp[b].begin(); mp[a][it->first]+=it->second; if(maxx[a]==mp[a][it->first]) sum[a]+=it->first; else if(maxx[a]<mp[a][it->first]) { maxx[a]=mp[a][it->first]; sum[a]=it->first; } mp[b].erase(it); } } void dfs(int u,int fa) { //cout<<u<<" "<<fa<<endl; mp[u][a[u]]++; maxx[u]=1; sum[u]=a[u]; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==fa)continue; dfs(v,u); update(u,v); } ans[u]=sum[u]; } /// 数组大小 int main() { init(); int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v),add(v,u); } dfs(1,-1); for(int i=1;i<=n;i++) printf("%lld ",ans[i]); return 0; }