2021牛客寒假算法基础集训营1 C

2021牛客寒假算法基础集训营1 C

题目链接:https://ac.nowcoder.com/acm/contest/9981/C

题目大意

你拿到了一棵树,请你给每个顶点染成红色或蓝色。

要求:每个红点周围有且仅有一个红点,每个蓝点周围有且仅有一个蓝点。

“周围”的定义:某点周围的点指通过邻边直接连接的点。

所谓树,即没有自环、重边和回路的无向连通图。

思路

对于一个叶子节点来说,由于除了父节点没有其他相邻节点,所以叶子节点的颜色一定和父节点颜色相同。那么我们可以用dfs来搜索,遇到叶子节点就把他和父节点标为同色。同时去掉这两个节点,就会产生新的叶子节点,如此递归到根节点。

那么无合法方案的情况有两种:

1.有一个父节点被多次与子节点标为同色

2.根节点没有标色

Code

#include<string>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define LL long long
#define MOD 1000000007
#define MAXN 100050
#define register long long
LL read()
{
	LL w = 1, x = 0;
	char ch = 0;
	while (ch < '0' || ch>'9')
	{
		if (ch == '-')
			w = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9')
	{
		x = x * 10 + (ch - '0');
		ch = getchar();
	}
	return w * x;
}
int n,head[110000],cnt,cn,ui,vi,p[110005],ans[110005];
struct node
{
	int to,next;
}edge[310005];
void add(int x,int y)
{
	edge[++cnt].to=y;
	edge[cnt].next=head[x];
	head[x]=cnt;
}
bool ok=0;
void dfs(int x,int fa)
{
	int son=0;
	for(int i=head[x];i;i=edge[i].next)
	{
		if(edge[i].to==fa)
			continue ;
		son++;
		dfs(edge[i].to,x);
	}
	if(son==0||p[x]==0)
	{
		if(p[fa])
		{
			ok=1;
			return ;
		}
		else
		{
			p[x]=++cn;
			p[fa]=cn;
		}
	}
}
void dfs1(int x,int fa)
{
	for(int i=head[x];i;i=edge[i].next)
	{
		if(edge[i].to==fa)
			continue ;
		if(p[edge[i].to]==p[x])
		{
			ans[edge[i].to]=ans[x];
		}
		else
		{
			ans[edge[i].to]=ans[x]^1;
			//ans[edge[i].to]%=2;
		}
		dfs1(edge[i].to,x);
	}
	
}
int main()
{
	n=read();
	for(int i=1;i<n;i++)
	{
		ui=read();
		vi=read();
		add(ui,vi);
		add(vi,ui);
	}
	dfs(1,0);
	if(ok||p[0])//p[0]!=0代表根节点与0节点同色,即根节点没有标色
	{
		cout<<"-1"<<endl;
	}
	else
	{
		ans[1]=1;
		dfs1(1,0);
		for(int i=1;i<=n;i++)
		{
			if(ans[i]==1)
			{
				cout<<'R'; 
			}
			else
			{
				cout<<'B';
			}
		}
		cout<<endl; 
	}
	return 0;
}
posted @ 2021-03-08 21:27  陆明燃  阅读(289)  评论(0)    收藏  举报