CodeForces - 964D Destruction of a Tree [dfs序+贪心]

题意:给你一棵树,只能将度为偶数的节点删除,并删除相连的边,求是否有一种方案将所有点删除。

题解:若(n-1)位偶数则肯定存在一种解法,然后我们贪心的从叶子节点开始往里删除,若当前节点能够被删除,再继续判断其子节点。

AC代码:

#include<stdio.h>
#include<vector>
#include<stack>
using namespace std;
vector<int>vt[200005];
vector<int>ans;
stack<int>sta;
int du[200005],fa[200005],mark[200005];
void dfs(int u,int f)
{
	fa[u]=f;
	sta.push(u);
	for(int i=0;i<vt[u].size();i++)
	{
		int to=vt[u][i];
		if(to==f)continue;
		dfs(to,u);
	}
}
void dfs(int u)
{
	ans.push_back(u);
	mark[u]=1;
	for(int i=0;i<vt[u].size();i++)
	{
		int to=vt[u][i];
		if(to==fa[u]||mark[to])continue;
		du[to]--;
		if(du[to]%2==0)
			dfs(to);
	}
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int k;
		scanf("%d",&k);
		if(k==0)continue;
		vt[k].push_back(i);
		vt[i].push_back(k);
		du[k]++;du[i]++;
	}
	dfs(1,1);
	while(!sta.empty())
	{
		int k=sta.top();
		sta.pop();
		if(du[k]%2==0)
		{
			ans.push_back(k);
			mark[k]=1;
			for(int i=0;i<vt[k].size();i++)
			{
				int to=vt[k][i];
				du[to]--;
				if(to==fa[k])continue;
				if(du[to]%2==0)
					dfs(to);
			}
		}
	}
	if(ans.size()!=n)printf("NO\n");
	else 
	{
		printf("YES\n");
		for(int i=0;i<n;i++)
			printf("%d\n",ans[i]);
	}
}


猜你喜欢

转载自blog.csdn.net/acterminate/article/details/80071229