其他分享
首页 > 其他分享> > Codeforces Global Round 16 E. Buds Re-hanging

Codeforces Global Round 16 E. Buds Re-hanging

作者:互联网

题目

题目大意

对于一棵树,定义了一个新的概念:
当一个结点的所有子节点都为叶子结点,该结点即为,但该结点不能为根结点。
现在给定一棵树,可以对该树操作任意次数以下操作:
将树的芽转移到其他结点。
现要求构造叶子数最少的树,输出其叶子数。

解题思路

对单一的芽分析:当我们找到了一个芽,我们可以将其转移到另一个叶子处,使得树的叶子数减少。
对整体分析:我们将树尽可能的拆成多个芽,如何重组能够使得叶子数最少?将芽放到叶子之后。
当我们将一个结点数为x的芽放入到树中时我们可以减少一个叶子增加x-1个叶子,于是我们开始尝试画图。
在这里插入图片描述
那么如何完成这个过程呢?尽可能的分成芽,并且拼接,那么代码来了!

code

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
const int maxn = 2e5 + 5;
int vis[maxn],n,res=1;
vector<int>a[maxn];
int dfs(int s,int fa)
{	
	int sum = 0;
	for(int i=0;i<a[s].size();i++)
	{
		if (a[s][i] == fa)continue;
		sum += dfs(a[s][i], s);
	}
	if(sum == 0)//判断是否为叶子
	{
		return 1;
	}
	else
	{
		res += sum - 1;//当sum不为0时说明这个结点为芽,那么答案就增加叶子数-1,即节点数-2。
		return 0;//当前结点为空。
	}
}
void solve()
{
	res = 1;
	cin >> n;
	for (int i = 1; i <= n; i++)a[i].clear();
	for(int i=1;i<n;i++)
	{
		int u, v;
		cin >> u >> v;
		a[u].pb(v);
		a[v].pb(u);
	}
	dfs(1, 0);
	cout << res << endl;
}
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	while (t--)solve();
	return 0;
}

标签:Buds,结点,return,16,int,res,sum,Global,叶子
来源: https://blog.csdn.net/m0_52186223/article/details/120354744