用两次bfs求出任意一条直径
对于该直径的所有点判断是否有非直径的点到该点距离最大值和直径起点S到该点的距离相同,若相同则说明从可以将原直径边换为该边,即该点为左分叉点,右分叉点同理
分别求出最靠右的左分叉点和最靠左的右分叉点,两分叉点之间的边即为直径的必经边
C++ 代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<string>
#include<cstring>
#include<bitset>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<iomanip>
#include<algorithm>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl "\n"
#define int long long
#define PI acos(-1)
//CLOCKS_PER_SEC clock()函数每秒执行次数
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 3e5+5,M = N * 2;
int mod = 1e9 +7;
int n,m,k,S,T;
int e[M],ne[M],w[M],h[N],idx;
void add(int a,int b,int c){
e[idx] = b,w[idx] = c,ne[idx] = h[a],h[a] = idx++;
}
int d[N],dis[N],pre[N];
int bfs(int s){
queue<int> q;
q.push(s);
memset(d,0,sizeof(d));
d[s] = 1;
dis[s] = 0;
while(!q.empty()){
int u = q.front();q.pop();
for(int i = h[u] ; ~i ; i = ne[i]){
int v = e[i];
if(!d[v]){
d[v] = d[u] + 1;
dis[v] = dis[u] + w[i];
pre[v] = i;
q.push(v);
}
}
}
int t = s;
for(int i = 1 ; i <= n ; ++i) if(dis[i] > dis[t]) t = i;
return t;
}
bool vis[N];
int f[N];
int l,r;
int dfs(int u,int fa){
if(f[u] != -1) return f[u];
f[u] = 0;
for(int i = h[u] ; ~i ; i = ne[i]){
int v = e[i];
if(v == fa) continue;
int t = dfs(v,u);
f[u] = max(f[u],t + w[i]);
//只用起点是直径点,走向非直径点的边更新
if(!vis[u] || vis[v]) continue;
if(f[v] + w[i] == dis[u] && d[u] > d[l]) l = u;
if(f[v] + w[i] == dis[T] - dis[u] && d[u] < d[r]) r = u;
}
}
void solve(){
cin >> n;
memset(h,-1,sizeof(h));
for(int i = 1 ; i < n ; ++i){
int a,b,c;
cin >> a >> b >> c;
add(a,b,c),add(b,a,c);
}
S = bfs(1);
T = bfs(S);
cout << dis[T] << endl;
for(int i = T ; ; i = e[pre[i] ^ 1]){
vis[i] = true;
if(i == S) break;
}
//记忆化搜索每个直径上的点的最长非直径边若和直径边相等这说明该点为分叉点
//l为左分叉点r为右分叉点
memset(f,-1,sizeof(f));
l = S,r = T;
dfs(S,-1);
cout << d[r] - d[l] << endl;
}
signed main(){
IOS;
solve();
return 0;
}
/*
*
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/