社区讨论

赛时奇妙思路。

P14637[NOIP2025] 树的价值参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mil8ya2o
此快照首次捕获于
2025/11/30 12:55
3 个月前
此快照最后确认于
2025/12/02 20:05
3 个月前
查看原帖
记录当前拓扑序下每个点到根节点的贡献最大的那个进行下一步赋值。 明显假的,但是玄学冲过了2个样例,洛谷能拿24. (但是似乎考场代码出了点问题……)
CPP
#include <bits/stdc++.h>
using namespace std;
#define int long long

int fa[100010];
int du[100010];
int to[100010];
int cnt;
int cont[100010];
int ji[100010];
int max1,max2;

void dfs(int x)
{
	if(x==0)
	{
		return;
	}
	ji[cont[x]]++;
	if(max1<ji[cont[x]])
	{
		max1=ji[cont[x]];
		max2=cont[x];
	}
	dfs(fa[x]);
}

void qing(int x)
{
	if(x==0)
	{
		return;
	}
	ji[cont[x]]=0;
	qing(fa[x]);
}

void gai(int x,int val)
{
	if(x==0)
	{
		return;
	}
	if(cont[x]==val)
	{
		cont[x]++;
	}
	gai(fa[x],val);
}


void topo()
{
	if(cnt==0)
	{
		return;
	}
	int max3=0,max4=0,add=0,max5=0;
	for(int i=1;i<=cnt;i++)
	{
		int x=to[i];
		qing(x);
		max1=0,max2=0;
		dfs(x);
		if(max1>max3)
		{
			max3=max1;
			add=max2;
			max4=x;
			max5=i;
		}
	}
	gai(max4,add);
	for(int i=max5;i<cnt;i++)
	{
		to[i]=to[i+1]; 
	}
	cnt--;
	du[fa[max4]]--;
	if(du[fa[max4]]==1&&fa[max4]!=1)
	{
		cnt++;
		to[cnt]=fa[max4];
	}
	topo();
}

main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		int n,h;
		cin>>n>>h;
		for(int i=2;i<=n;i++)
		{
			cin>>fa[i];
			du[fa[i]]++;
			du[i]++;
		}
		for(int i=2;i<=n;i++)
		{
			if(du[i]==1)
			{
				cnt++;
				to[cnt]=i;
			}
		}
		topo();
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			ans+=cont[i];
		}
		cout<<ans+1<<endl;
		for(int i=0;i<=n;i++)
		{
			cont[i]=0;
			fa[i]=0;
			du[i]=0;
			to[i]=0;
			ji[i]=0;
		}
	}
}

回复

0 条回复,欢迎继续交流。

正在加载回复...