为了更好的阅读体检,为了更好的阅读体检,,可以查看我的算法学习博客第二题-必经之路
在线评测链接:P1167
题目内容
塔子哥的班主任最近组织了一次户外拓展活动,让班里的同学们一起去爬山。在路上,塔子哥看到了一棵漂亮的树,他对这棵树产生了浓厚的兴趣,开始观察并记录这棵树的一些特征。
塔子哥发现这棵树有 n 个节点,其中有一条边被特别标记了出来。他开始思考这条特殊的边在树上起到了什么样的作用,于是他想知道,经过这条选定边的所有树上简单路径中,最长的那条路径有多长,以便更好地理解这棵树的结构。
一条简单的路径的长度指这条简单路径上的边的个数。
输入描述
第一行一个整数 n ,表示树的节点个数。
第二行 n-1 个整数,第 i 个数 表示节点 i+1 和
之间有一条边相连。
第三行两个整数 x , y ,表示这条选定的边。保证这条边一定是树上的一条边。
对于全部数据, ,
,
,
。
保证输入数据正确描述一棵树,并且( x, y ) 是树上的条边。
输出描述
输出一行,一个整数,表示所有经过选定边的树上简单路径中,最长的那条的长度。
样例
输入
7 1 2 3 4 5 3 3 7
输出*
4
思路
树上dfs
由于是一棵树,所以将 (x,y) 这条边删除后,树就被拆分为两棵树。
接着分别以 x 和 y 为根对两棵子树 dfs 求出最大深度即可。
时间复杂度:O(n)
类似题目推荐
这道题是非常经典,也非常"裸"的树上dfs问题。LeetCode上有非常多的例题,并且在2023年春招过程中考了114514次。望周知。
LeetCode
-
112. 路径总和
-
129. 求根到叶子节点数字之和
-
236. 二叉树的最近公共祖先
CodeFun2000
难度依次递增
1.P1141 2023.04.01-美团-第五题-染色の树
2.P1224 携程 2023.04.15-春招-第三题-魔法之树
3.P1159. 2022年清华大学(深圳)保研夏令营机试题-第一题-树上计数
4.P1196 华为 2023-04-19-第二题-塔子哥出城
5.P1044. 拼多多内推笔试-2023.2.22.投喂珍珠
6.P1193. 腾讯音乐 2023.04.13-暑期实习-第二题-价值二叉树
更多请见:知识点分类-训练-深度优先搜索专栏
代码
CPP
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
// 读入
vector<vector<int>> g(n);
for (int i = 2; i <= n; ++i) {
int p; cin >> p;
g[p - 1].emplace_back(i - 1);
g[i - 1].emplace_back(p - 1);
}
// C++11特性:匿名函数
function<int(int,int)> dfs = [&](int u, int fa) {
int res = 0;
for (int v: g[u]) {
if (v == fa) continue;
res = max(res, dfs(v, u) + 1);
}
return res;
};
int x, y;
cin >> x >> y;
x -= 1;
y -= 1;
// 拆成两部分dfs
cout << dfs(x, y) + dfs(y, x) + 1 << "n";
return 0;
}
python
# 读入 n = int(input()) p = list(map(int, input().split(" "))) g = [[] for i in range(n)] for i in range(2, n + 1): g[i - 1].append(p[i - 2] - 1) g[p[i - 2] - 1].append(i - 1) x, y = map(int, input().split(" ")) x -= 1 y -= 1 def dfs(u, fa): res = 0 for v in g[u]: if v == fa: continue res = max(res, dfs(v, u) + 1) return res # 根据题意拆成两部分 print(dfs(x, y) + dfs(y, x) + 1)Java
import java.util.*; public class Main { static List<List<Integer>> g; public static void main(String[] args) { // 读入 Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); g = new ArrayList<>(); for (int i = 0; i < n; i++) { g.add(new ArrayList<>()); } for (int i = 2; i <= n; i++) { int p = scanner.nextInt(); g.get(i - 1).add(p - 1); g.get(p - 1).add(i - 1); } int x = scanner.nextInt() - 1; int y = scanner.nextInt() - 1; // 根据题意拆成两部分dfs System.out.println(dfs(x, y) + dfs(y, x) + 1); } private static int dfs(int u, int fa) { int res = 0; for (int v : g.get(u)) { if (v == fa) { continue; } res = Math.max(res, dfs(v, u) + 1); } return res; } }
Js
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let input = '';
process.stdin.on('data', (data) => {
input += data;
return;
});
process.stdin.on('end', () => {
const lines = input.trim().split('n');
const n = parseInt(lines[0]);
const p = lines[1].split(' ').map(Number);
const g = new Array(n + 5).fill();
for (var i = 1 ; i <= n ; i++) g[i] = [];
for (let i = 2; i <= n ; i++) {
g[i].push(p[i - 2]);
g[p[i - 2]].push(i);
}
let [x, y] = lines[2].split(' ').map(Number);
console.log(dfs(x, y , g) + dfs(y, x , g) + 1);
});
function dfs(u, fa , g) {
let res = 0;
for (const v of g[u]) {
if (v === fa) continue;
res = Math.max(res, dfs(v, u , g) + 1);
}
return res;
}
Go
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
sc := bufio.NewReader(os.Stdin)
var n int
fmt.Fscanln(sc, &n)
edges := [][]int{}
for i := 1; i < n; i++ {
var pi int
fmt.Fscan(sc, &pi)
edges = append(edges, []int{i + 1, pi})
}
fmt.Fscanln(sc)
var x, y int
fmt.Fscanln(sc, &x, &y)
test14(n, edges, x, y)
}
func test14(n int, edges [][]int, x, y int) {
// 建图
graph := map[int][]int{}
for _, edge := range edges {
graph[edge[0]] = append(graph[edge[0]], edge[1])
graph[edge[1]] = append(graph[edge[1]], edge[0])
}
// 分别从 x, y 向两边延伸, 分别得到最长的, 相加 + 1
visitedMap := map[int]bool{}
var dfs func(node int) int
dfs = func(node int) int {
if len(graph[node]) == 0 {
return 1
}
res := 0
for _, next := range graph[node] {
if !visitedMap[next] {
visitedMap[next] = true
res = max(res, 1+dfs(next))
visitedMap[next] = false
}
}
return res
}
visitedMap[x] = true
visitedMap[y] = true
resX, resY := dfs(x), dfs(y)
fmt.Println(resX + resY + 1)
}
func max(a, b int) int {
if a > b {
return a
}
return b
}



















