题目链接: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;
}

(Codeforces798Div2)C. Infected Tree(思维)相关推荐

  1. Infected Tree(递归/树形)

    Infected Tree 传送门 Problem - C - Codeforces 思路 一开始第一眼以为是树形dp,就先把每个节点下面的节点个数(不包括自己)全求出来了,然后后面发现没用- 然后又 ...

  2. Codeforces Round #798 C. Infected Tree

    Byteland is a beautiful land known because of its beautiful trees. Misha has found a binary tree wit ...

  3. [dfs][思维]Infected Tree CF1689C

    Byteland is a beautiful land known because of its beautiful trees. Misha has found a binary tree wit ...

  4. C. Infected Tree(思维/dfs/树形dp)

    题目 题意: 给定一颗树 ,根节点为2,每个结点的子节点数不超过2(也就是说这是一个二叉树).现在根节点被感染了,我们需要拯救这棵树. 有n次过程,每次过程如下: 我们可以选择砍掉一个非感染点,使得该 ...

  5. Codeforces Round #624 (Div. 3) E. Construct the Binary Tree 思维 + 构造

    传送门 文章目录 题意: 思路: 题意: 给你n,dn,dn,d,让你构造有nnn个点的二叉树,他们每个节点深度和为ddd. n,d≤3000n,d\le 3000n,d≤3000. 思路: 先考虑不 ...

  6. HDU - 5573 Binary Tree(思维+构造+二进制)

    题目链接:点击查看 题目大意:给出一棵无限大的完全二叉树,每次给出一个 n 和一个 k ,要求从点 1 出发一直向下,找到一条长度为 k 的路径,对于路径上的点可以加上其编号,也可以减去其编号,需要构 ...

  7. CodeForces - 618D Hamiltonian Spanning Tree(思维+贪心)

    题目链接:点击查看 题目大意:首先给出n个点,n*(n-1)/2条边组成的无向图,边的权值为y,现在给出一棵连接n个点的树,树上的权值都是x,现在问如何在每个点只遍历一次的情况下走遍n个点,并使一路上 ...

  8. D. Serval and Rooted Tree(思维+树形dp+二分辅助)

    https://codeforces.com/problemset/problem/1153/D 思路:参考issue https://issue-is-vegetable.blog.csdn.net ...

  9. C - Infected Tree

    一个简单的dp ,统计每一个结点包括自身和所有下属结点的个数sum,并统计每一个结点感染后可以保存最多多少个结点ss表示,如果他的分支为0就是0为1就是他的儿子结点的sum-1,如果为2则是max(a ...

最新文章

  1. 基于关键帧的RGB-D视觉惯性里程计
  2. 某程序员总结大厂程序员性格:阿里出来的是人精!百度出来的脾气好!美图出来的一根筋!头条出来的心高气傲!京东出来的满嘴是兄弟!...
  3. C++学习之路: 单例模板
  4. DCMTK:将PDF文件封装为DICOM文件
  5. throws与throw
  6. mysql设计功能设置表_MySQL数据表的设计
  7. Vue2 彻底从 Flow 重构为 TypeScript,焕然一新!
  8. ASP.NET Core 源码学习之 Options[4]:IOptionsMonitor
  9. leetcode129. 求根到叶子节点数字之和(dfs)
  10. java sqlite 操作_Java SQLite 数据库操作
  11. groupby索引有效吗_两千字揭密 MySQL 8.0.19 三大索引新功能
  12. 远程诊断技术在汽车 OTA 刷新应用的研究
  13. 浏览器清除缓存快捷键
  14. 解决异常 more than one ‘primary‘ bean found among candidates: [jacksonObjectMapper, objectMapper]
  15. JS async库:parallel, series, waterfall, whilst用法
  16. 汤姆猫炫跑鸿蒙,汤姆猫炫跑游戏怎么操作-玩法规则一览
  17. 【Linux】3.0Linux进程概念
  18. google的秘密入口+搜索技巧
  19. Selenium+Python+Pycharm自动化环境搭建具体步骤
  20. MATLAB几个误差参数说明

热门文章

  1. 关于windows10系统下没有选择双系统的界面直接进入windows10的解答
  2. Linux之数据提取操作
  3. Ubuntu下的docker搭建及基础使用
  4. C语言:L1-016 查验身份证 (15 分)
  5. Object C 实现简单打卡APP
  6. SQL Server本地Windows身份登录,错误代码18456问题
  7. windows卸载mysql,重新安装
  8. 【转帖】十大已死和垂死IT技术和职业
  9. IDEA中文乱码怎么办
  10. 嵌入式系统 - 任务