树上启发式合并,码风清新,没过样例
  • 板块CF600E Lomsat gelral
  • 楼主YGW6
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/7/22 17:55
  • 上次更新2024/7/22 19:33:52
查看原帖
树上启发式合并,码风清新,没过样例
938950
YGW6楼主2024/7/22 17:55

有部分注释

看不懂就@我

没过样例,不知道问题出在哪里

#include<iostream>
#include<cmath>
#include<string>
#include<string.h>
#include<algorithm>
#define int long long

using namespace std;

const int N=1e5+5;

int n;
int c[N],ans[N],ap[N];//ap:颜色出现的次数 
int sum,maxx;

int hson[N],size[N];
//hson[u]:u的重儿子 
//size[u]:u的子树大小 

struct edge
{
	int u,v;
}e[N];
int h[N],cnt;

void add(int u,int v)
{
	e[++cnt].v=v;
	e[cnt].u=h[u];
	h[u]=cnt;
}

void dfs1(int u,int fa)
{
	size[u]=1;
	for(int i=h[u];i!=-1;i=e[i].u)
	{
		int v=e[i].v;
		if(fa==v)
			continue;
		dfs1(v,u);
		size[u]+=size[v];
		if(size[hson[u]]<size[v])
			hson[u]=v;//更新重儿子 
	}
}

void init(int u,int fa)
{
	--ap[c[u]];
	for(int i=h[u];i!=-1;i=e[i].u)
	{
		int v=e[i].v;
		if(v==fa)//||v==hson[u]
			continue;
		init(v,u);
	}
}

void work(int u,int fa)
{
	++ap[c[u]];
	if(ap[c[u]]>maxx)
	{
		maxx=ap[c[u]];
		sum=c[u];
	}
	else if(ap[c[u]]==maxx)
		sum+=c[u];
	for(int i=h[u];i!=-1;i=e[i].u)
	{
		int v=e[i].v;
		if(v==fa||v==hson[u])
			continue;
		work(v,u);
	}
}

void dfs2(int u,int f)
{
	for(int i=h[u];i!=-1;i=e[i].u)
	{
		int v=e[i].v;
		if(v==hson[u]||f==v)
			continue;
		dfs2(v,u);
		init(v,u);
		sum=maxx=0;
	}
	if(hson[u])
		dfs2(hson[u],u);
	work(u,f);
	ans[u]=sum;
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	memset(h,-1,sizeof h);
	for(int i=1;i<=n;i++)
		cin>>c[i];
	for(int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		add(u,v);
		add(v,u);//建边 
	}
	dfs1(1,0);//预处理 
	dfs2(1,0);
	for(int i=1;i<=n;i++)
		cout<<ans[i]<<" ";
	cout<<endl;
	return 0;
}
2024/7/22 17:55
加载中...