题目描述
You are given a rooted tree with root in vertex 1 . Each vertex is coloured in some colour.
Let's call colour c dominating in the subtree of vertex v if there are no other colours that appear in the subtree of vertex v more times than colour c . So it's possible that two or more colours will be dominating in the subtree of some vertex.
The subtree of vertex v is the vertex v and all other vertices that contains vertex v in each path to the root.
For each vertex v find the sum of all dominating colours in the subtree of vertex v .
输入格式
The first line contains integer n ( 1<=n<=105 ) — the number of vertices in the tree.
The second line contains n integers ci ( 1<=ci<=n ), ci — the colour of the i -th vertex.
Each of the next n−1 lines contains two integers xj,yj ( 1<=xj,yj<=n ) — the edge of the tree. The first vertex is the root of the tree.
输出格式
Print n integers — the sums of dominating colours for each vertex.
隐藏翻译
题意翻译
- 有一棵 n 个结点的以 1 号结点为根的有根树。
- 每个结点都有一个颜色,颜色是以编号表示的, i 号结点的颜色编号为 ci。
- 如果一种颜色在以 x 为根的子树内出现次数最多,称其在以 x 为根的子树中占主导地位。显然,同一子树中可能有多种颜色占主导地位。
- 你的任务是对于每一个 i∈[1,n],求出以 i 为根的子树中,占主导地位的颜色的编号和。
- n≤105,ci≤n
洛谷崩掉了,cf交的超时,我也不知道怎么办了
好的现在不超时了。dfs_son函数 原本是return int值 改成void就不超时了
原本的单链表存储改成vector了
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,color[N],cnt[N];
int sz[N],son[N],idx=0;
int mx;
ll ans[N],sum;
vector<vector<int>>g(N);
void dfs_son(int u,int father){
sz[u]=1;
for(auto i:g[u]){
if(i==father)continue;
dfs_son(i,u);
sz[u]+=sz[i];
if(sz[i]>sz[son[u]])son[u]=i;
}
}
void update(int u,int father,int sign,int pson){
int c=color[u];
cnt[c]+=sign;
if(cnt[c]>mx)mx=cnt[c],sum=c;
else if(cnt[c]==mx)sum+=c;
for(int i:g[u]){
if(i==father||i==pson)continue;
update(i,u,sign,pson);
}
}
void dfs(int u,int father,int op){
for(auto i:g[u]){
if(i==father||i==son[u])continue;
dfs(i,u,0);
}
if(son[u])dfs(son[u],u,1);
update(u,father,1,son[u]);
ans[u]=sum;
if(!op)update(u,father,-1,0),sum=mx=0;
}
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;++i)cin>>color[i];
int x,y;
for(int i=0;i<n-1;++i){
cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs_son(1,0);
dfs(1,0,1);
for(int i=1;i<=n;++i)cout<<ans[i]<<" ";
return 0;
}
单链表版
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5*2+10;
int n,color[N],cnt[N];
int h[N],e[N],ne[N],sz[N],son[N],idx=0;
int mx;
ll ans[N],sum;
void add(int x,int y){
e[idx]=y,ne[idx]=h[x],h[x]=idx++;
}
void dfs_son(int u,int father){
sz[u]=1;
for(int i=h[u];~i;i=ne[i]){
int j=e[i];
if(j==father)continue;
dfs_son(j,u);
sz[u]+=sz[j];
if(sz[j]>sz[son[u]])son[u]=j;
}
}
void update(int u,int father,int sign,int pson){
int c=color[u];
cnt[c]+=sign;
if(cnt[c]>mx)mx=cnt[c],sum=c;
else if(cnt[c]==mx)sum+=c;
for(int i=h[u];~i;i=ne[i]){
int j=e[i];
if(j==father||j==pson)continue;
update(j,u,sign,pson);
}
}
void dfs(int u,int father,int op){
for(int i=h[u];~i;i=ne[i]){
int j=e[i];
if(j==father||j==son[u])continue;
dfs(j,u,0);
}
if(son[u])dfs(son[u],u,1);
update(u,father,1,son[u]);
ans[u]=sum;
if(!op)update(u,father,-1,0),sum=mx=0;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d",&color[i]);
memset(h,-1,sizeof(h));
int x,y;
for(int i=0;i<n-1;++i){
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs_son(1,-1);
dfs(1,-1,1);
for(int i=1;i<=n;++i)printf("%lld ",ans[i]);
return 0;
}