CF763A Timofey and a tree 题解

分析

乱搞题。

优先考虑 DP。定义状态函数 fi 表示在以 1 为根时,i 为根的子树中颜色是否相同。如果对于 1 的每一个儿子 j,都有 fj=1,则输出 1 就行。

考虑换根的情况。在以 ii1)为根的时候,原本是 i 的儿子的节点还是其节点。这时候 i 的父节点也将成为儿子。而 i 的父节点为根的子树中的节点就是除了 i 为根的子树外的所有节点。搞一个 DFS 序,定义 wi 表示在 DFS 序中,节点 i 的位置;sizi 表示节点 i 所在的子树节点数量。则在以 i 为根的时候,其原本的父节点为根的子树就是 [1,wi1][wi+sizi,n] 中的所有节点。

原来的儿子判定直接像节点 1 那样就行。而对于新的儿子,判定两个区间是否颜色全部相同,乱搞个分块就行。在这里,1 节点是必回出现的,所以我们可以以 1 的颜色为基准来判定。

复杂度 O(nn)

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define re register
#define il inline

const int N=2e5+10;
int n,col[N];
int ne[N],e[N],h[N],idx;
int s[N],len;
int where[N],dfsx[N],siz[N],fath[N],cnt;
int f[N];

il void add(int a,int b){ne[++idx]=h[a],e[idx]=b,h[a]=idx;}
il void dfs(int now,int fa){
	siz[now]=1,fath[now]=fa,
	dfsx[++cnt]=now,where[now]=cnt,
	f[now]=1;
	for(re int i=h[now];i;i=ne[i]){
		int j=e[i];if(j==fa) continue;
		dfs(j,now);siz[now]+=siz[j];
		if(col[j]!=col[now]) f[now]=0;
		f[now]=min(f[now],f[j]);
	}
}

il int get(int x){return (x-1)/len+1;}
il int query(int l,int r,int x){
	if(l>r) return 1;
	int bl=get(l),br=get(r),ans=0;
	if(bl==br){
		for(re int i=l;i<=r;++i) 
			if(col[dfsx[i]]!=x) return 0;
		return 1;
	}
	else{
		for(re int i=l;i<=bl*len;++i)
			if(col[dfsx[i]]!=x) return 0;
		for(re int i=bl+1;i<br;++i)
			if(s[i]!=len||col[dfsx[i*len]]!=x) return 0;
		for(re int i=(br-1)*len+1;i<=r;++i)
			if(col[dfsx[i]]!=x) return 0;
		return 1;
	}
}

il void solve(){
	cin>>n;len=sqrt(n);
	for(re int i=1,u,v;i<n;++i) cin>>u>>v,add(u,v),add(v,u);
	for(re int i=1;i<=n;++i) cin>>col[i];
	dfs(1,0);
	for(re int i=1;i<=n;++i) s[get(i)]+=((col[dfsx[i]]==col[dfsx[i-1]])||(!s[get(i)]));
	for(re int i=1;i<=n;++i)
		if(i==1){
			bool fl=0;
			for(re int j=h[i];j;j=ne[j]) if(!f[e[j]]) fl=1;
			if(!fl){cout<<"YES\n"<<i;return;}
		}
		else{
			bool fl=0;
			for(re int j=h[i];j;j=ne[j]) if(!f[e[j]]&&e[j]!=fath[i]) fl=1;
			if(fl) continue;
			if(query(1,where[i]-1,col[1])&&query(where[i]+siz[i]-1+1,n,col[1])){cout<<"YES\n"<<i;return;}
		}
	cout<<"NO";return;
}

signed main(){
	solve();
	return 0;
}
posted @   harmis_yz  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示