1 条题解
-
0
一、题意回顾(精简版)
给定一棵 个节点的树。 对所有有序对 ,,两人进行博弈:
- Nora 先手,只能从 向外扩展毛虫;
- Aron 后手,只能从 向外扩展毛虫;
- 若 是叶子,Nora 胜;
- 若 是叶子,Aron 胜;
- 初始两者都是叶子,或 轮未分胜负,则平局。
求:使得 Aron 必胜的有序对 数量。
二、结论性转化(本题核心)
通过博弈分析与树上结构观察,可以得出:
Aron 获胜的充要条件
满足下列两类之一:
-
初始直接获胜 是叶子,且 不是叶子。
-
博弈后获胜 满足:
- 不是叶子;
- 不是叶子;
- 是全内部点(所有邻居都不是叶子);
- 是非全内部点(至少有一个邻居是叶子)。
三、定义与符号
为方便表述,统一符号:
-
:节点 的度数
-
叶子:,记叶子集合为 数量:
-
内部点:
对内部点 ,定义:
-
: 的邻居中也是内部点的数量
-
全内部点(记为集合 ): 满足 ,即所有邻居都是内部点 数量:
-
非全内部点(记为集合 ): 内部点但 ,即至少一个邻居是叶子
四、答案公式
最终答案由两部分相加:
[ \mathrm{ans}=c_1\cdot(n-c_1);+;c_2\cdot\sum_{m\in T}\big(d(m)-1\big) ]
逐项解释:
- 第一部分 [ c_1 \cdot (n - c_1) ]
- :叶子 的数量
- :非叶子 的数量
- 含义:所有满足 是叶子, 不是叶子 的有序对,Aron 直接获胜。
- 第二部分 [ c_2 \cdot \sum_{m\in T}\big(d(m)-1\big) ]
- :全内部点 的数量
- 对每个非全内部点 (作为 ),贡献为
- 含义:博弈后 Aron 能必胜的有序对数量。
五、标程逐段解释
1. 基础预处理
int n; cin >> n; for (int i=1;i<n;++i) { int u,v; cin>>u>>v; g[u].push_back(v); g[v].push_back(u); }读入树,建邻接表。
2. 统计叶子数量
int c1=0; for(int i=1;i<=n;++i) c1 += (deg(i)==1);- 是叶子
然后计算第一部分答案:
ans += 1LL * c1 * (n - c1);
3. 统计 与全内部点数量
for(int i=1;i<=n;++i) if(deg(i)>1){ for(int v:g[i]) d[i] += (deg(v)>1); c2 += (d[i]==deg(i)); }- 只对内部点计算
- :邻居中内部点个数
- 若 ,则 , 加一
4. 计算第二部分答案
for(int m=1;m<=n;++m) if(deg(m)>1 && d[m]!=deg(m)) ans += 1LL * c2 * (d[m]-1);- 遍历所有非全内部点
- 每个贡献
- 乘上全内部点数量
六、复杂度分析
- 建树:
- 遍历统计度数、:
- 每组测试用例总复杂度:
满足约束:
七、样例验证(第二个样例)
输入:
5 1 2 1 3 2 4 2 5节点度数:
因此:
- 叶子:
- 非叶子:
- 第一部分:
内部点:
- :邻居只有 (内部点) 全内部点
- :邻居 (内部)、(叶)、(叶)
非全内部点只有 ,贡献 第二部分:
总答案: 与样例输出一致。
八、总结
本题表面是复杂树上博弈,实际结论非常简洁:
[ \boxed{\mathrm{ans}=c_1(n-c_1);+;c_2\sum_{m\in T}\big(d(m)-1\big)} ]
标程正是严格按照该公式线性计算,时间效率最优、代码极简洁。
- 1
信息
- ID
- 6610
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者