【Codeforces】Codeforces Round 866 (Div. 2) E.The Fox and the Complete Tree Traver | 树

标题链接

Problem – E – Codeforces

标题

【Codeforces】CF Round 866 (Div. 2) E.The Fox and the Complete Tree Traver | 树

标题粗心

在一棵有 nn 个节点的树上,狐狸能够从极点 vv 跳动到另一个极点 uu 当且仅当这些极点之间的间隔不超越 22

换句话说,假如极点 vvuu 之间有边直接相连,或者存在这样的极点 ww 使得极点 vvww 之间有边、极点 uuww 之间有边,狐狸就能够在一次跳动中从极点 vv 到达极点 uu

求树上是否有循环路线 v1,v2,…,vnv_1,v_2,…,v_n 使得:狐狸能够从极点 viv_i 跳到极点 vi+1v_{i+1},狐狸能够从极点 vnv_n 跳到极点 v1v_1,且一切 viv_i 是成对不同的。

思路

简单通过手玩发现假如树上存在下图所示结构那么必定无解。

【Codeforces】CF Round 866 (Div. 2) E.The Fox and the Complete Tree Traver | 树

所以有解的树必定是一条链上挂着若干个叶子节点的结构。

我们首先要 check 整棵树是否是有解的形状,只需要将一切度为 11 的节点删除,若剩余的节点不是一条链即无解,假如剩余的部分存在度大于 22 的节点即可说明不是链。

【Codeforces】CF Round 866 (Div. 2) E.The Fox and the Complete Tree Traver | 树

在有解的情况下,一种合法的构造解的方案是:

首先将剩余的链拎出来,即用数组 ansans 顺序存储图中的橙色节点。

先正着遍历一遍 ansans 数组,遍历到第 ii 个节点时,若 ii 为奇数就输出橙色节点 ans[i]ans[i],不然输出节点 ii 上挂着的绿色节点。

再倒着遍历一遍 ansans 数组,遍历到第 ii 个节点时,若 ii 为偶数就输出橙色节点 ans[i]ans[i],不然输出节点 ii 上挂着的绿色节点。

上图的遍历成果如下所示。

【Codeforces】CF Round 866 (Div. 2) E.The Fox and the Complete Tree Traver | 树

代码

#include <bits/stdc++.h>
using namespace std;
const int N=200005;
int n,d[N],ans[N],tot;
vector<int>e[N],t;
int main()
{
	scanf("%d",&n);
	for (int x,y,i=1;i<n;++i)
	{
		scanf("%d%d",&x,&y);
		e[x].push_back(y);
		e[y].push_back(x);
		d[x]++;
		d[y]++;
	}
	for (int i=1;i<=n;++i)
		if (d[i]==1) t.push_back(i),d[i]=0;
	for (auto i:t)
		for (auto v:e[i]) d[v]--;
	int id=1;
	for (int i=1;i<=n;++i)
	{
		if (d[i]==1) id=i;
		if (d[i]>2) return printf("No\n"),0;
	}
	printf("Yes\n");
	memset(d,0,sizeof(d));
	for (int i=id,fa=0,flg=1;flg;)
	{
		ans[++tot]=i;
		flg=0;
		for (auto v:e[i])
			if (v!=fa&&e[v].size()!=1)
			{
				fa=i;
				i=v;
				flg=1;
				break;
			}
	}
	for (int i=1;i<=tot;++i)
	{
		if (i&1) printf("%d ",ans[i]);
		else 
		{
			for (auto v:e[ans[i]])
				if (v!=ans[i-1]&&v!=ans[i+1]) printf("%d ",v);
		}
	}
	for (int i=tot;i>=1;--i)
	{
		if (i&1)
		{
			for (auto v:e[ans[i]])
				if (v!=ans[i-1]&&v!=ans[i+1]) printf("%d ",v);
		}
		else printf("%d ",ans[i]);
	}
	return 0;
}