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