题解:CF979C Kuro and Walking Route
Luo_Yicheng · · 题解
题意
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); //双向存图 } - 我们知道这棵树共有
n\times(n-1) 个(u,v) 对。且不难发现,若u 是x 节点的子树,且v 是y 节点的子树,那么u 到v 的路径就一定不合规。我们可以以y 为根节点,遍历这棵树到达x 结束,则n 减去遍历过的节点数量,就是x 的子树大小。求y 用一样的思路。这样我们就可以得出,若x 的子树大小为sx ,y 为sy ,不合规的点对数量为sx\times sy ,答案则为n\times(n-1)-sx\times sy 。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 } }总结
时间复杂度:
O(n) 。
空间复杂度:
代码可通过: