Find the end points of the diameter of all trees

Given a nnFor a tree with n nodes, solve the endpoints of all diameters in this tree.

Solution: the
first time dfsor bfsstarting from any point, usually choose 1 1Point 1 , find the distance1 11 dot all the furthest pointspoints pointsp o i n t s . They are the end points of the diameter of the tree.
Then frompointsp o i n t s choose a pointrtas thedfsorbfsstart point, findrtall the points farthest from the point, they are also the end points of the diameter of the tree.
Since the points of the first traversal and the second traversal may be repeated:
such as a3 3Tree with 3 points:
edge1 − 2 1-212
sides1 − 3 1-313
second choice2 2When point 2 is the starting point,3 3Point 3 will be selected again, so it needs to be de-duplicated.
You can useset setS E T or a direct manual de-emphasis.

Proof:
Prove why you only need pointsP O I n- T S optionally one point to run the second pass.
The initial point of the second traversal isuuu , the farthest point traversed isvvv
alluuu 's nearest common ancestor isroot rootr o o t
thenu − v uvuv must go throughroot rootR & lt O O T 's.

  • If vvv p o i n t s points In p o i n t s , it is equivalent tovvv One of the farthest places you can run isuuu , so the points will not be missed.
  • If vvv不在 p o i n t s points points中, p o i n t s points The farthest other points in p o i n t s reach must also havevvv , which is equivalent to running at a different starting point, but these starting points go toroot rootR o o t are all the same distance, and they must pass through theroot rootr o o t reachvvv , so the distance is:dis (root, u) + dis (root, v) dis(root,u)+dis(root,v)dis(root,u )+dis(root,v )

Example: the
deepest root

Sample code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

#define sz(x) (int)x.size()

const int N = 20010, M = 20010;
int n;
int h[N], e[M], ne[M], idx;
int p[N];
int ans[N], g;
int dis[N];
void add(int a, int b) {
    
    
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

int find(int x) {
    
    
    if(x != p[x]) p[x] = find(p[x]);
    return p[x];
}

int rt, mx = -1;
void dfs(int u, int fa, int dep) {
    
    
    if(dep > mx) mx = dep, rt = u;
    dis[u] = dep;
    for(int i = h[u]; ~i; i = ne[i]) {
    
    
        int v = e[i];
        if(v == fa) continue;
        dfs(v, u, dep + 1);
    }
}

void dfs2(int u, int fa, int dep) {
    
    
    mx = max(mx, dep);
    dis[u] = dep;
    for(int i = h[u]; ~i; i = ne[i]) {
    
    
        int v = e[i];
        if(v == fa) continue;
        dfs2(v, u, dep + 1);
    }
}

int main()
{
    
    
    scanf("%d", &n);
    memset(h, -1, n + 1 << 2);
    int cnt = n;
    for(int i = 1; i <= n; ++i) p[i] = i;
    for(int i = 1; i < n; ++i) {
    
    
        int a, b; scanf("%d%d", &a, &b);
        if(find(a) != find(b)) {
    
    
            p[find(a)] = p[find(b)];
            --cnt;
        }
        add(a, b);
        add(b, a);
    }
    
    if(cnt != 1) printf("Error: %d components\n", cnt);
    else {
    
    
        dfs(1, -1, 0);
        for(int i = 1; i <= n; ++i)
            if(dis[i] == mx) ans[++g] = i;
            
        mx = -1;
        dfs2(rt, 0, 0);
        
        for(int i = 1; i <= n; ++i) 
            if(dis[i] == mx) ans[++g] = i;
        sort(ans + 1, ans + g + 1);
        n = unique(ans + 1, ans + g + 1) - ans - 1;
        for(int i = 1; i <= n; ++i) printf("%d\n", ans[i]);
    }
    
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43900869/article/details/114181648