給出一顆 n 個節點的樹,求樹上最遠點對。
用 d p[
i]dp[i]
dp[i
] 維護以 i 為根的子樹的深度,dp[
i]=m
ax(d
p[i]
,dp[
j]+1
)dp[i] = max(dp[i], dp[j]+1)
dp[i]=
max(
dp[i
],dp
[j]+
1)(j 為 i 的兒子)。
求出任意節點 i 子樹深度之後,經過 i 的最長路徑就是最深的兩顆子樹深度相加。
上述狀態轉移方程只維護了最深的,需要改變一下,現在要求出最深的兩個相加。維護兩個變數 m1, m2,用 if 判斷即可。
最後答案是所有最長路徑中最長的。
不一定是經過根節點的最長路徑。
#include
using namespace std;
typedef
long
long ll;
const ll mod =
9999991
;const
int n =
1e5+10;
int n, x, y, r;
vector<
int> son[n]
;int rt[n]
, dp[n]
;//dp[i] 代表以 i 為跟的子樹深度
intdp
(int rt)
else
if(dp[x]+1
> m2)
} dp[rt]
= m1;
return m1 + m2;
}int
main()
for(
int i =
1; i <= n; i++)if
(!rt[i]
)printf
("%d\n",dp
(r))
;return0;
}
2602 樹的直徑(最遠點對,樹狀dp
一棵樹的直徑就是這棵樹上存在的最長路徑。現在有一棵n個節點的樹,現在想知道這棵樹的直徑包含的邊的個數是多少?如圖所示的資料,這棵樹的直徑為 1 2 3 6 9 這條路徑,包含的邊的個數為4,所以答案是4。輸入第1行 乙個整數n,表示樹上的節點個數。1 n 100000 第2 n行 每行有兩個整數u,...
樹的直徑(最遠距離)
輸入資料 5 51 2 2 2 4 3 2 5 1 4 5 4 1 3 5 有5個點5條邊 第一次bfs從1號點開始找到最遠距離3號距離為5 第二次bfs從3號點開始找最遠距離點10 include include include define max 100000 using namespace ...
51nod 1803 森林的直徑
題目中生成樹的方式可以生成任何一種形狀的 n 節點樹。這是因為樹也是da g圖.任何形狀的樹,都可以拓撲排序後重新標號。我們計算這種方式生成的樹的期望深度。其實就是隨機生成一棵樹的期望深度。但是平均不代表不能代表特殊。更具體來說,對於 n 個節點的隨機樹。最大深度超過 h時候大概率是多少?是否有絕對...