[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=3124
[算法]
树的直径
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 200010 struct edge { int to,w,nxt; } e[MAXN << 1]; int i,n,s,t,cnt,tmp,tot,u,v,w,l,r; long long mx; int path[MAXN],head[MAXN],pre[MAXN]; long long dist[MAXN]; bool visited[MAXN]; inline void addedge(int u,int v,int w) { tot++; e[tot] = (edge){v,w,head[u]}; head[u] = tot; } inline int bfs(int s) { int i,u,v,w,l,r,pos; static int q[MAXN]; static bool visited[MAXN]; for (i = 1; i <= n; i++) visited[i] = false; q[l = r = 1] = s; dist[s] = 0; pre[s] = 0; visited[s] = true; while (l <= r) { u = q[l]; l++; for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; w = e[i].w; if (!visited[v]) { visited[v] = true; dist[v] = (long long)dist[u] + w; pre[v] = u; q[++r] = v; } } } pos = 1; for (i = 2; i <= n; i++) { if (dist[i] > dist[pos]) pos = i; } return pos; } inline void dfs(int u,int fa,long long sum) { int i,v,w; mx = max(mx,sum); for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; w = e[i].w; if (v != fa && !visited[v]) dfs(v,u,sum + w); } } int main() { scanf("%d",&n); for (i = 1; i < n; i++) { scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); } s = bfs(1); t = bfs(s); printf("%lld ",dist[t]); tmp = t; while (tmp != 0) { path[++cnt] = tmp; tmp = pre[tmp]; visited[tmp] = true; } reverse(path + 1,path + cnt + 1); l = 1,r = cnt; for (i = cnt; i >= 1; i--) { mx = 0; dfs(path[i],0,0); if (!mx) continue; if (mx == dist[t] - dist[path[i]]) r = i; if (mx == dist[path[i]]) { l = i; break; } } printf("%d ",r - l); return 0; }