Three Paths on a Tree

Portal

Title description

Find three points x, y, z in a tree, requiring the largest distance between the three points,

analysis

First we can find the diameter of this tree, and then go to find another point to the shortest diameter on this tree

My initial idea was to find the end points of the diameter by three times of bfs, and process the distance from each point to the two end points of the diameter, and then give each one that meets d1[x] + d2[x] == d (d is Mark the point of the diameter of the tree) and mess with it. Later I found it was troublesome.

We directly find the distance from each point to the two ends of the diameter, and then add the length of the diameter. In this way, each distance is added again, and finally the whole is divided by 2.

Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define _CRT_SECURE_NO_WARNINGS
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC option("arch=native","tune=native","no-zero-upper")
#pragma GCC target("avx2")
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10,M = 4e5 + 10;
int h[N],ne[M],e[M],idx;
int st[N];
int is[N];
int d1[N],d2[N];
int d[N];
int n;

void add(int x,int y){
    
    
    ne[idx] = h[x],e[idx] = y,h[x] = idx++;
}

int main(){
    
    
    int x = 0,y = 0,z = 0;
    int ans = 0;
    memset(h,-1,sizeof h);
    scanf("%d",&n);
    for(int i = 1;i < n;i++){
    
    
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y),add(y,x);
    }
    queue<int> Q;
    Q.push(1);
    st[1] = true;
    while(Q.size()){
    
    
        int t = Q.front();
        Q.pop();
        for(int i = h[t];~i;i = ne[i]){
    
    
            int j = e[i];
            if(st[j]) continue;
            d1[j] = d1[t] + 1;
            st[j] = true;
            Q.push(j);
        }
    }
    for(int i = 1;i <= n;i++)
        if(d1[i] > d1[x]) x = i;
    Q.push(x);
    memset(st,0,sizeof st);
    st[x] = true;
    while(Q.size()){
    
    
        int t = Q.front();
        Q.pop();
        for(int i = h[t];~i;i = ne[i]){
    
    
            int j = e[i];
            if(st[j]) continue;
            st[j] = true;
            d2[j] = d2[t] + 1;
            Q.push(j);
        }
    }
    for(int i = 1;i <= n;i++)
        if(d2[i] > d2[y]) y = i;
    Q.push(y);
    memset(st,0,sizeof st);
    st[y] = true;
    d1[y] = 0;
    while(Q.size()){
    
    
        int t = Q.front();
        Q.pop();
        for(int i = h[t];~i;i = ne[i]){
    
    
            int j = e[i];
            if(st[j]) continue;
            st[j] = true;
            d1[j] = d1[t] + 1;
            Q.push(j);
        }
    }
    int back = 0;
    for(int i = 1;i <= n;i++){
    
    
        if(i == x || i == y) continue;
        back = (d1[i] + d2[i] + d1[x]) / 2;
        if(back > ans){
    
    
            ans = back;
            z = i;
        }
    }
    printf("%d\n",ans);
    printf("%d %d %d\n",x,y,z);
    return 0;
}

/**
*  ┏┓   ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃       ┃
* ┃   ━   ┃ ++ + + +
*  ████━████+
*  ◥██◤ ◥██◤ +
* ┃   ┻   ┃
* ┃       ┃ + +
* ┗━┓   ┏━┛
*   ┃   ┃ + + + +Code is far away from  
*   ┃   ┃ + bug with the animal protecting
*   ┃    ┗━━━┓ 神兽保佑,代码无bug 
*   ┃        ┣┓
*    ┃        ┏┛
*     ┗┓┓┏━┳┓┏┛ + + + +
*    ┃┫┫ ┃┫┫
*    ┗┻┛ ┗┻┛+ + + +
*/

Guess you like

Origin blog.csdn.net/tlyzxc/article/details/112214264