专栏文章
CF755C PolandBall and Forest - Solution
CF755C题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mingr39x
- 此快照首次捕获于
- 2025/12/02 02:09 3 个月前
- 此快照最后确认于
- 2025/12/02 02:09 3 个月前
现在有一个未知的森林,给 个数的序列, 代表离 最远的点中编号最小的一个,根据这个信息还原出森林中有多少棵树。
离一个结点最远的点 一定是直径端点之一,否则将直径锯断连向 ,一定可以构造出一个更长的直径。
孤立点是平凡的,以下的树默认结点数都大于 。
结点大于 的树一定至少有两个直径端点,而且由于本题目同时限制了另一个直径端点必须是编号最小的,所以一棵树的直径也是唯一确定的。
所以当一个点 在树中的时候, 是它所在树的一个直径端点,另一方面,当一棵树存在的时候,其两个直径端点一定都在 中出现过(两个端点各自的 就是对方)。
于是我们不妨计数不同的 的个数 ,树的数量可以被孤立点数加 确定。
一个树不会漏,因为它是非孤立点,一定有两个不同的直径端点;也不会重,因为满足题目限制的直径是唯一的。这样可以就 做完。
可以说明本题直接将 和 相连并求连通块数是正确的。因为你注意到这玩意实际上跟上面的东西等价,但是这样转化没有什么必要。
CPPint n, x, a[maxn], ans;
int main() {
scanf("%d", &n);
rep(i, 1, n) scanf("%d", &x), ans += (x == i), a[x] |= (x != i); int s = 0;
rep(i, 1, n) if (a[i]) ++s; ans += s / 2;
printf("%d\n", ans);
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...