专栏文章
题解:CF979C Kuro and Walking Route
CF979C题解参与者 1已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mio3wu4n
- 此快照首次捕获于
- 2025/12/02 12:57 3 个月前
- 此快照最后确认于
- 2025/12/02 12:57 3 个月前
题意
Kuro 想要在一棵树上选择两个不同的节点 和 作为步行路线的起点和终点。但是,他避免选择那些路径上先经过节点 再经过节点 的 对。需要计算所有满足条件的 对的数量。
分析
算法
图的遍历。
数据结构
数组,STL vector(邻接表存图)。
过程分析
观察到 ,考虑 做法,即每个节点只遍历一次。
步骤:存图,DFS 两次计算 节点的子树大小。
详细解法
- 输入 + 存图
cin >> n >> x >> y;
for (int i = 1; i < n; i++){
int a, b;
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a); //双向存图
}
- 我们知道这棵树共有 个 对。且不难发现,若 是 节点的子树,且 是 节点的子树,那么 到 的路径就一定不合规。我们可以以 为根节点,遍历这棵树到达 结束,则 减去遍历过的节点数量,就是 的子树大小。求 用一样的思路。这样我们就可以得出,若 的子树大小为 , 为 ,不合规的点对数量为 ,答案则为 。
shouldnot = y; //不能走到的节点
dfs(x, x); //从 x 开始遍历
int ans = n - sum; //记录子树大小
sum = 0;
shouldnot = x; //重置
dfs(y, y);
ans *= (n - sum);
cout << (n - 1) * n - ans;
- DFS 内部。
void dfs(int u, int f){ //当前节点和父节点
if (u == shouldnot)
return; //如果走到 shouldnot 节点,结束 DFS。
sum++; //累加遍历过的数量
for (int i : g[u]){ //遍历所有能到达的节点
if (i != f) //防止走会父节点
dfs(i, u); //更新 u,f
}
}
总结
时间复杂度:。
空间复杂度:。
代码可通过:


相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...