(Codeforces798Div2)C. Infected Tree(思维)

该博客讨论了一种二叉树模型中的病毒感染问题。每秒病毒会感染一个子节点,同时可以砍掉一个未感染节点以拯救其子树。目标是最大化拯救的节点数。博主通过深度优先搜索分析了最佳策略,即寻找最近的叶子节点或单分支节点来决定何时砍枝,从而得出可拯救的节点数量。代码实现中展示了如何遍历树并计算最大拯救节点数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:Problem - C - Codeforces

 样例输入:

4
2
1 2
4
1 2
2 3
2 4
7
1 2
1 5
2 3
2 4
5 6
5 7
15
1 2
2 3
3 4
4 5
4 6
3 7
2 8
1 9
9 10
9 11
10 12
10 13
11 14
11 15

样例输出:

0
2
2
10

题意:

多组样例,给定一个具有n个结点的二叉树,根节点被病毒感染了。

每秒会有以下事件发生:

我们可以砍掉一个还未被感染的结点,那么以这个结点为根的子树上的结点全部都获救了。

被感染的点会把其孩子结点全部感染

我们现在要求最多能够拯救的结点数量。

分析:由于题目中说明树是一棵二叉树,所以我们每次就是砍掉一个分支,另一个分支的子树的根节点被感染,那么我们很容易想到,正常情况下每过一秒就会有一个结点被感染且有一个结点被砍掉,那这种情况会持续到什么时候呢?就是当遍历到一个叶子结点时,这个叶子结点会被直接感染,同时我们把他的兄弟结点砍掉而导致整个过程结束,还有一种情况就是遍历到一个只有一个分支的情况,那么下一个过程,这个单分支结点会被直接感染,那么我们这个分支根节点被感染后我们直接砍去他唯一的孩子结点,那么整个过程也就结束了,这两种情况分别对应着下面的左图和右图:

 如果理解了上面的分析相信大家就能看到,每经过一秒,就会有两个结点牺牲,直到遇到单分支结点或者叶子结点为止,如果遇到单分支结点,最后就是单分支的孩子结点被砍,而如果是叶子结点,那么最后就是叶子结点被感染,通过这样的分析,大家肯定能发现每经过一秒牺牲的结点所在的层次数就会+1,直到遇到上面两种情况为止,所以题目就转化为求出距离根节点最近的叶子结点或者是单分支结点,如果距离根节点的最近结点是叶子结点,那么牺牲的结点数就是叶子结点所在的层数*2-1,而如果距离根节点的最近结点是单分支结点,那么牺牲的结点数就是单分支结点所在层数*2,答案就是总结点个数减去牺牲的结点个数即可。

注意根节点由于没有父节点,所以他的出边要比正常结点少1,所以需要特殊判断一下。

下面是代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
const int N=1e6+10;
int n,ans;
vector<int>p[N];
void dfs(int x,int fa,int d)
{
	if(p[x].size()==2&&x!=1)
	{
		ans=max(ans,n-2*d);
		return ;
	}
	else if(p[x].size()==1)
	{
		if(x!=1)
			ans=max(ans,n-(2*d-1));
		else ans=n-2;
		return ;
	}
	for(int i=0;i<p[x].size();i++)
	{
		int j=p[x][i];
		if(j==fa) continue;
		dfs(j,x,d+1);
	}
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			p[i].clear();
		ans=0;
		int u,v;
		for(int i=1;i<n;i++)
		{
			scanf("%d%d",&u,&v);
			p[u].push_back(v);
			p[v].push_back(u);
		}
		dfs(1,0,1);
		printf("%d\n",ans);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值