博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[计蒜客T2237]魔法_树
阅读量:4543 次
发布时间:2019-06-08

本文共 1300 字,大约阅读时间需要 4 分钟。

魔法

题目大意

数据范围


题解

这个题挺好玩的

可以用反证法,发现所有叶子必须都得选而且所有叶子都选了合法。

故此我们就是要使得,一次操作之后使得叶子的个数最少。

这怎么弄呢?

我们发现,如果一条边相连的两个点$x$和$y$($d_i$表示点$i$的度数,不妨设$d_x\le d_y$)满足:

$d_y\ge 3$且$d_x\ge 3$,那么叶子可以$-=2$。

如果$d_y\ge 3$且$d_x\le 2$,那么叶子可以$-=1$。

枚举每条边,看看最多能$-1$还是$-2$就好了~

代码

#include 
#define N 200010 using namespace std;int head[N], to[N << 1], nxt[N << 1], tot;char *p1, *p2, buf[100000];#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )int rd() { int x = 0, f = 1; char c = nc(); while (c < 48) { if (c == '-') f = -1; c = nc(); } while (c > 47) { x = (((x << 2) + x) << 1) + (c ^ 48), c = nc(); } return x * f;}inline void add(int x, int y) { to[ ++ tot] = y; nxt[tot] = head[x]; head[x] = tot;}int d[N], x[N], y[N];int main() { int n = rd(), k = rd(); for (int i = 2; i <= n; i ++ ) { x[i] = rd(), y[i] = rd(); d[x[i]] ++ ; d[y[i]] ++ ; } int mx = 0; for (int i = 2; i <= n; i ++ ) { int s1 = d[x[i]], s2 = d[y[i]]; if (s1 < s2) swap(s1, s2); if (s1 >= 3) { if (s2 >= 3) { mx = max(mx, 2); } else if(s2 <= 2) { mx = max(mx, 1); } } } int sum = 0; for (int i = 1; i <= n; i ++ ) { if (d[i] == 1) { sum ++ ; } } mx *= k; cout << sum - mx << endl ; return 0;}

小结:有意思的题~

转载于:https://www.cnblogs.com/ShuraK/p/11256684.html

你可能感兴趣的文章
word2010更改样式
查看>>
百家姓
查看>>
Xcode代码提示里的字母含义
查看>>
[CQOI2017]小Q的表格(数论+分块)
查看>>
leetcode59
查看>>
tcp eaddrnotavail
查看>>
同步带传动张紧轮位置估算
查看>>
Access连接字符串
查看>>
python单元测试框架pytest——fixture函数(类似unitest的setup和teardown)
查看>>
Hadoop源码分析8: IPC流程(3)客户端的clients、connections、calls复用
查看>>
[MVC]View
查看>>
Django REST FRAMEWORK swagger(二)model序列化
查看>>
一点随想
查看>>
SVN操作步骤
查看>>
Xianqi UVa 1589
查看>>
无刷新效果统计在线人数
查看>>
2017-2018-2 1723《程序设计与数据结构》问题汇总 (更新完毕)
查看>>
c# 通过反射 实例化类
查看>>
[ubuntu]中文用户目录路径改英文
查看>>
spark 编程教程
查看>>