Educational Codeforces Round 47 (Rated for Div. 2) F. Dominant Indices(dsu on tree)

题目链接:http://codeforces.com/contest/1009/problem/F

 

出题人的黑科技,貌似子树中的静态查询问题都可以这么用啊?

http://codeforces.com/blog/entry/44351

 

代码:

#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define xx first
#define yy second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int MAXN=1e6+5;
vector<int> E[MAXN];
int sz[MAXN],dp[MAXN],in[MAXN],out[MAXN],cnt[MAXN],ver[MAXN],ans[MAXN];
int tim=0;
void dfs_1(int now,int f,int d)
{
	in[now]=++tim;
	ver[tim]=now;
	sz[now]=1;dp[now]=d;
	for(auto v:E[now])
	{
		if(v==f) continue;
		dfs_1(v,now,d+1);
		sz[now]+=sz[v];
	}
	out[now]=tim;
}
void dfs_2(int now,int f,bool keep)
{
	int bigson=-1,mx=-1;
	for(auto v:E[now])
	{
		if(v==f) continue;
		if(sz[v]>mx)
		{
			mx=sz[v];
			bigson=v;
		}
	}
	for(auto v:E[now])
	{
		if(v==f||v==bigson) continue;
		dfs_2(v,now,0);
	}
	if(bigson!=-1) dfs_2(bigson,now,1);
	mx=-1;int id=dp[now];
	if(bigson!=-1) mx=cnt[dp[bigson]+ans[bigson]],id=dp[bigson]+ans[bigson];
	for(auto v:E[now])
	{
		if(v==f||v==bigson) continue;
		for(int i=in[v];i<=out[v];i++)
		{
			cnt[dp[ver[i]]]++;
			if(cnt[dp[ver[i]]]==mx)
				id=min(id,dp[ver[i]]);
			if(cnt[dp[ver[i]]]>mx)
			{
				mx=cnt[dp[ver[i]]];
				id=dp[ver[i]];
			}
		}
	}
	cnt[dp[now]]++;
	if(cnt[dp[now]]==mx)
		id=min(id,dp[now]);
	if(cnt[dp[now]]>mx)
	{
		mx=cnt[dp[now]];
		id=dp[now];
	}
	ans[now]=id-dp[now];
	if(!keep)
		for(int i=in[now];i<=out[now];i++)
		{
			cnt[dp[ver[i]]]--;
		}
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int n;
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		E[u].pb(v);E[v].pb(u);
	}
	dfs_1(1,0,0);
	dfs_2(1,0,1);
	for(int i=1;i<=n;i++)
		printf("%d\n",ans[i]);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值