完全沒有時間想這道題,碼了個暴力還忘記清空陣列了。。方法其實很簡單,跟以前考的一道題類似。
首先把樹建處理出倍增祖先陣列,然後對每個聯通塊維護它的直徑的端點。
合併兩個聯通塊時新的直徑的端點一定是這兩個聯通塊的4個端點中的兩個。
那麼可以暴力列舉是哪兩個即可。
/*******************************
author:galaxy yr
lang:c++
created time:2023年10月21日 星期一 15時11分58秒
*******************************/
#include
#include
#include
using
namespace std;
struct io
}cin;
struct edge};
struct node
node
(int a=0,
int b=0,
int c=0)
:x(a),
y(b),w
(c)}
;const
int maxn=
3e5+10;
const
int lg=18;
int n,a[maxn]
,b[maxn]
,head[maxn]
,cnt,f[maxn]
[lg+1]
,fa[maxn]
,x[maxn]
,y[maxn]
,depth[maxn]
;edge e[maxn<<1]
;void
add(
int u,
int v)
void
dfs(
int now,
int fa)
intfind
(int x)
intlca
(int x,
int y)
intget_dis
(int x,
int y)
void
check
(int a,
int b,
int x,
int y,
int f)
intmerge
(int x,
int y)
intmain()
dfs(1,
0);for
(int i=
2;i<=n;i++
)printf
("%d\n"
,merge
(a[i]
,b[i]))
;return0;
}
用線段樹維護樹的直徑
有時候我們需要快速回答一棵子樹的直徑,或者去掉一棵子樹後形成的樹的直徑。普通的找直徑方法是兩遍bfs,時間o n 這裡的方法用o log 的時間回答。我們做出一棵樹的dfs序,然後以dfs序為軸建立線段樹,每個區間維護直徑 len,以及直徑的兩個端點 x 和 y。會有這麼乙個問題 你按線段樹劃分區間...
To Heart 題解 樹的直徑
給定一棵樹,樹中每條邊都有乙個權值,樹中兩點之間的距離定義為連線兩點的路徑邊權之和。樹中最遠的兩個節點 兩個節點肯定都是葉子節點 之間的距離被稱為樹的直徑,連線這兩點的路徑被稱為樹的最長鏈。後者通常也可稱為直徑。我們設1號節點為根節點,那麼最短路徑則是到根節點最遠的乙個節點與次遠的乙個節點的距離之和...
C 題解 樹的直徑
樹中兩點間的不重複經過的邊和點道路稱為兩點的路徑,路徑的長度 路徑上所經邊的長度和 稱為兩點的距離。圓的直徑是乙個圓的最長的一條弦,而樹的直徑是樹中兩點間最長的路徑。通常用乙個無序點對 x,y 表示一棵樹的直徑。現在輸入乙個有n個結點的樹,結點編號為1到n,假設結點1為根。試求樹的直徑。輸入格式 輸...