标签:
树的直径必然取自某个节点的两个(或一个)最深的子树,可以一遍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;
}
标签:
原文地址:http://www.cnblogs.com/xblade/p/4478218.html