0x01 前置芝士

树形结构?贪心?思维?眼睛?

好有趣。。。 link

0x02

题目大意:给你一颗有 \(n\) 个节点的树,你需要尽可能多的删掉边,使得剩下的图中有 \(k\) 个点满足互相能走到。求最后剩下的边数。

我们深度剖析出题人其实是想考树形 \(dp\) 的,可是呢,这其实就是道一眼题。

首先,我们剩下的图最优情况一定是只剩 \(k\) 个点。

对于答案,最优的情况其实就是 \(k\) 个点分成 \(\lfloor \frac k 2 \rfloor\) 堆,使得每一堆只有两个点或有一堆有三个点。这也是最理想的情况,但显然一些树无法满足。不过你会发现,这个理想情况最后剩的边为 \(\lceil \frac k 2 \rceil\)。

于是我们考虑原树可以拆分成多少个多少堆,使得每一堆的点数不大于 \(2\),记能拆分出的个数为 \(cnt\)。

如果 \(cnt >= \lfloor \frac k 2 \rfloor\),也就是说这棵树可以拆分出这么多堆,那么答案就是 \(\lceil \frac k 2 \rceil\)。

而如果 \(cnt < \lfloor \frac k 2 \rfloor\),也就是说这棵树是不支持最优解的,那么我们就运用一下贪心。首先我们需要剩余 \(k\) 个点,而因为我们原树只能拆出 \(cnt\) 堆,所以说这 \(k\) 个点中,一定有 \(cnt \times 2\) 个点可以成为理想情况。那么我们就考虑剩下 \(k - cnt \times 2\) 个点怎么办。其实我也不知道怎么办,但我知道这些点一定能通过一条边和已经处于理想情况的一堆连接起来,那么累加边即可。此时答案为 \(k - cnt \times 2 + cnt\),即 \(k - cnt\)。

把这两种情况综合一下就会得到答案:\(k - \min(\lfloor \frac k 2 \rfloor, cnt)\)。

关于 \(cnt\) 的求法,我们可以直接遍历这棵树。

对于节点 \(u\),它的子节点 \(v\),如果所有的 \(v\) 被取用过,我们就不取,并把 \(u\) 设为未被取用;如果有一个 \(v\) 没有被取用,我们就取没被取用的第一个 \(v\) 并把 \(u\) 设为被取用。可以结合代码分析。

0x03 code

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std; typedef long long LL;
int read() {
int x = 0, k = 1;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + (s ^ 48);
s = getchar();
}
return x * k;
} void write(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
} void print(int x, char s) {
write(x);
putchar(s);
} int Min(int x, int y) { return x < y ? x : y; } const int MAXN = 1e5 + 5;
int son[MAXN], dp[MAXN];
vector<int> mp[MAXN]; void Add_Edge(int u, int v) {
mp[u].push_back(v);
mp[v].push_back(u);
} int cnt = 0;
bool Tree_Dp(int u, int fa) {
bool f = 1;
for (int i = 0; i < mp[u].size(); i++) {
int v = mp[u][i];
if (v == fa)
continue;
int t = Tree_Dp(v, u);
if (f && t) {
f = 0;
cnt++;
}
}
return f;
} int main() {
int T = read();
while (T--) {
int n = read(), k = read();
for (int i = 1; i <= n; i++) mp[i].clear();
for (int i = 1; i < n; i++) {
int u = read(), v = i + 1;
Add_Edge(u, v);
}
for (int i = 1; i <= n; i++) son[i] = mp[i].size();
cnt = 0;
Tree_Dp(1, 0);
print(k - Min(cnt, k >> 1), '\n');
}
return 0;
}

Solution -「Local 11145」诗意狗的更多相关文章

  1. Solution -「ARC 104E」Random LIS

    \(\mathcal{Description}\)   Link.   给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...

  2. Solution -「LOCAL」二进制的世界

    \(\mathcal{Description}\)   OurOJ.   给定序列 \(\{a_n\}\) 和一个二元运算 \(\operatorname{op}\in\{\operatorname{ ...

  3. Solution -「LOCAL」大括号树

    \(\mathcal{Description}\)   OurTeam & OurOJ.   给定一棵 \(n\) 个顶点的树,每个顶点标有字符 ( 或 ).将从 \(u\) 到 \(v\) ...

  4. Solution -「LOCAL」过河

    \(\mathcal{Description}\)   一段坐标轴 \([0,L]\),从 \(0\) 出发,每次可以 \(+a\) 或 \(-b\),但不能越出 \([0,L]\).求可达的整点数. ...

  5. Solution -「LOCAL」Drainage System

    \(\mathcal{Description}\)   合并果子,初始果子的权值在 \(1\sim n\) 之间,权值为 \(i\) 的有 \(a_i\) 个.每次可以挑 \(x\in[L,R]\) ...

  6. Solution -「LOCAL」Burning Flowers

      灼之花好评,条条生日快乐(假装现在 8.15)! \(\mathcal{Description}\)   给定一棵以 \(1\) 为根的树,第 \(i\) 个结点有颜色 \(c_i\) 和光亮值 ...

  7. Solution -「LOCAL」画画图

    \(\mathcal{Description}\)   OurTeam.   给定一棵 \(n\) 个点的树形随机的带边权树,求所有含奇数条边的路径中位数之和.树形生成方式为随机取不连通两点连边直到全 ...

  8. Solution -「LOCAL」ZB 平衡树

    \(\mathcal{Description}\)   OurOJ.   维护一列二元组 \((a,b)\),给定初始 \(n\) 个元素,接下来 \(m\) 次操作: 在某个位置插入一个二元组: 翻 ...

  9. Solution -「LOCAL」舟游

    \(\mathcal{Description}\)   \(n\) 中卡牌,每种三张.对于一次 \(m\) 连抽,前 \(m-1\) 次抽到第 \(i\) 种的概率是 \(p_i\),第 \(m\) ...

随机推荐

  1. spring 拦截器流程 HandlerInterceptor AsyncHandlerInterceptor HandlerInterceptorAdapter

    HandlerInterceptor源码 3种方法: preHandle:拦截于请求刚进入时,进行判断,需要boolean返回值,如果返回true将继续执行,如果返回false,将不进行执行.一般用于 ...

  2. 尾递归与 memorize 优化

    尾递归与 memorize 优化 本文写于 2020 年 12 月 10 日 递归 递归是一种非常常见的算法思维,在大家刚开始学编程的时候应该就会接触到. 我们可以这么理解递归: function 讲 ...

  3. .Net 在容器中操作宿主机

    方案描述 在 docker 容器中想操作宿主机,一般会使用 ssh 的方式,然后 .Net 通过执行远程 ssh 指令来操作宿主机.本文将使用 交互式 .Net 容器版 中提供的镜像演示 .Net 在 ...

  4. 万字+28张图带你探秘小而美的规则引擎框架LiteFlow

    大家好,今天给大家介绍一款轻量.快速.稳定可编排的组件式规则引擎框架LiteFlow. 一.LiteFlow的介绍 LiteFlow官方网站和代码仓库地址 官方网站:https://yomahub.c ...

  5. javaweb开发案例

    1.实验3 (1)当运行Servlet时,碰到"空指针异常"错误怎么处理? 答:应提示用户操作有误,或设置对象值为空字符串或一个默认值,或是不执行某操作,直接跳转到其他处理中. ( ...

  6. 深度学习与CV教程(4) | 神经网络与反向传播

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/37 本文地址:http://www.showmeai.tech/article-det ...

  7. python3在使用类基础时,遇到错误TypeError: module.**init**() takes at most 2 arguments (3 given)

    python3在使用类基础时,遇到错误TypeError: module.init() takes at most 2 arguments (3 given) 1.原因:直接导入的py文件,而没有导入 ...

  8. 2021年第十二届蓝桥杯javaA组省赛部分题目

    试题 D: 路径 本题总分:10 分 [问题描述] 小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图 中的最短路径. 小蓝的图由 2021 个结点组成,依次编号 1 至 2021. 对 ...

  9. 【原创】项目三Raven-2

    实战流程 1,C段扫描,并发现目标ip是192.168.186.141 nmap -sP 192.168.186.0/24 扫描目标主机全端口 nmap -p- 192.168.186.141 访问8 ...

  10. 2021.06.05【NOIP提高B组】模拟 总结

    T1 题意:给你一个 \(n\) 个点 \(n\) 条边的有向图, 求每个店经过 \(K\) 条边后的边权和.最小边权 \(K\le 10^{10}\) 考试时:一直想着环,结果一直不知道怎么做 正解 ...