树的直径必然取自某个节点的两个(或一个)最深的子树,可以一遍DFS解决。
#include <iostream> #include <algorithm> #include <vector> using namespace std; vector<int> tree[100005]; bool has_parent[100005] = { false }; int max_length[100005]; int ans; void solve(int root_idx) { int lgst = 0, lgst_idx = 0; int size = tree[root_idx].size(); for (int i = 0; i < size; i++) { // 递归求树深 int sub_idx = tree[root_idx][i]; solve(sub_idx); if (lgst < max_length[sub_idx]) { lgst = max_length[sub_idx]; lgst_idx = i; } } max_length[root_idx] = lgst + 1; int sec_lgst = 0; for (int i = 0; i < size; i++) { // 次深子树深度 int sub_idx = tree[root_idx][i]; if (sec_lgst < max_length[sub_idx] && i != lgst_idx) { sec_lgst = max_length[sub_idx]; } } ans = max(ans, lgst + sec_lgst); } int main() { int n; cin >> n; for(int i = 1; i < n; i++) { int a, b; cin >> a >> b; if (has_parent[a]) { tree[a].push_back(b); has_parent[b] = true; } else { tree[b].push_back(a); has_parent[a] = true; } } for (int i = 1; i <= n; i++) { if (!has_parent[i]) { solve(i); break; } } cout << ans << endl; return 0; }
另一种做法是两遍BFS:以任一个节点为根BFS找到最远的节点,再从该节点BFS找到的最长路径就是直径。
#include <iostream> #include <algorithm> #include <vector> #include <cstring> using namespace std; vector<int> tree[100005]; int length[100005]; int max_length, max_idx; void bfs(int root_idx, int pa_idx, int depth) { length[root_idx] = depth; if (max_length < depth) { max_length = depth; max_idx = root_idx; } int len = tree[root_idx].size(); for (int i = 0; i < len; i++) { int sub_idx = tree[root_idx][i]; if (sub_idx != pa_idx) { bfs(sub_idx, root_idx, depth + 1); } } } int main() { int n; cin >> n; for(int i = 1; i < n; i++) { int a, b; cin >> a >> b; tree[a].push_back(b); tree[b].push_back(a); } bfs(1, -1, 0); bfs(max_idx, -1, 0); cout << max_length << endl; return 0; }
时间: 2024-10-13 10:56:58