樹上的一些基礎操作

Zhang_Wenjie發表於2024-07-08

樹的直徑

樹的直徑就是樹上最遠兩點間簡單路徑的距離,也就是樹上最長的簡單路徑。

可以用 樹形 dp 的思想做

考察樹上任意節點 u,若它有 i 條子樹,則就有 i 條過 u 點(嚴格是以 u 為端點)的路徑,要找到 懸掛 在 u 點的最長路徑,貪心地想就是找到 最長路徑次長路徑 合起來就是過 u 點的可能解

設 d1,d2 分別表示最長路徑,次長路徑,邊界肯定就是 0(只有該點)

對於 (u, v) 方向上的子樹路徑長度 d,可以遞推求解

  • d > d1,則 d2 = d1, d1 = d
  • d > d2,則 d2 = d

結果就是對所有點的最長路徑取最大值 \(\max\limits_{i\in V}\{d1_i + d2_i\}\),複雜度 \(O(n)\)

int dfs(int u, int fa)
{
	int d1 = 0, d2 = 0;
	
	for (re i = h[u]; i; i = e[i].next)
	{
		int v = e[i].to, w = e[i].w;
		if (v == fa) continue;
		
		int d = dfs(v, u) + w;
		if (d > d1) d2 = d1, d1 = d;
		else if (d > d2) d2 = d;
	}
	res = max(res, d1 + d2);
	
	return d1;
}

相關文章