Skip to content

Commit

Permalink
Try to fix textlint errory again
Browse files Browse the repository at this point in the history
  • Loading branch information
gilbert12tw committed Aug 29, 2023
1 parent 393bcc5 commit 138712c
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 14 deletions.
27 changes: 15 additions & 12 deletions src/graph/centroid.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@

### 如何求重心?

通常我們要先求出子樹大小才能找重心,所以我們可以任選一個點當根,先求出每個節點子樹大小。接著開始從根開始遞迴檢查,遍歷所有子節點,如果有一個子節點子樹大小 \\( > \frac{N}{2} \\), 則重心一定在這個個子樹裡,所以就往這個子節點遞迴。反之如果所有子節點子樹大小都不超過一半,則現在所在的點即為重心。
通常我們要先求出子樹大小才能找重心,所以我們可以任選一個點當根,先求出每個節點子樹大小。接著開始從根開始遞迴檢查,遍歷所有子節點,如果有一個子節點子樹大小 \\( > \frac{n}{2} \\), 則重心一定在這個個子樹裡,所以就往這個子節點遞迴。反之如果所有子節點子樹大小都不超過一半,則現在所在的點即為重心。

另一種實作方式是一樣是任選一個點當根,先算出所有子樹大小,再透過整棵樹大小減去每個節點的子樹大小的方式,算出每個點父親節點所形成的子樹大小來判斷。

> [CSES Finding a Centroid](https://cses.fi/problemset/task/2079)
>
> 給一棵 \\(N\\) 個節點的樹,輸出樹的重心編號
> 給一棵 \\(n\\) 個節點的樹,輸出樹的重心編號
>
> - \\( 1 \le N \le 2 \times 10 ^ 5 \\)
> - \\( 1 \le n \le 2 \times 10 ^ 5 \\)
<details><summary> Sample Code </summary>

Expand Down Expand Up @@ -108,10 +108,11 @@ int main() {
> [BOI Village (Maximum)](https://codeforces.com/contest/1387/problem/B2)
>
> 有一座 \\(N\\) 個點的樹形成鎮,每一個點住著一位居民,編號從 \\( 1 \sim N \\)。
> 有一天,居民們突然想要搬家,每個居民都要搬到不同的節點,但一個節點只能住一位居民,一個居民的搬家距離為舊家到新家的路徑上的邊數。> 請你給出一種搬家方案使所有居民的搬家距離總和最大。
> 有一座 \\(n\\) 個點的樹形成鎮,每一個點住著一位居民,編號從 \\( 1 \sim n \\)。
> 有一天,居民們突然想要搬家,每個居民都要搬到不同的節點,但一個節點只能住一位居民,一個居民的搬家距離為舊家到新家的路徑上的邊數。
> 請你給出一種搬家方案使所有居民的搬家距離總和最大。
>
> - \\(1 \le N \le 10^5 \\)
> - \\(1 \le n \le 10^5 \\)
對於每一條邊 \\( (u, v) \\),將這條邊斷開後會把樹分成兩棵大小分別為 \\( SZ_u, SZ_v \\)的樹,所以這條邊至多對答案貢獻 \\( 2 \times \min(SZ_u, SZ_v) \\) (乘以 \\(2\\) 是因為兩個方向都最多被經過 \\( \min(SZ_u, SZ_v) \\) 次)。所以考慮每條邊的貢獻,答案最大會是
\\(\begin{equation*} \sum\limits_{(u, v) \in E} \min \\{SZ_u, SZ_v\\} \end{equation*}\\)。
Expand All @@ -120,15 +121,17 @@ int main() {
所以我們考慮以重心當根,則根節點的所有子樹大小都會 \\( < \frac{n}{2} \\),有很多種方式可以構造出解答,這邊講一個實作起來最簡單的。
我們將以重心為根的樹先進行一次 DFS,並將依照每個點的拜訪順序紀錄成一個陣列 \\( a \\),將 \\(a\\) 向右循環平移 \\( \lfloor\frac{n}{2}\rfloor \\)得到新的陣列 \\(b\\),接著 \\( \forall{i \in 1 \sim N} \\),將 \\(a_i\\) 搬到 \\(b_i\\),這樣就得到一組解了。
我們將以重心為根的樹先進行一次 DFS,並將依照每個點的拜訪順序紀錄成一個陣列 \\( a \\),將 \\(a\\) 向右循環平移 \\( \lfloor\frac{n}{2}\rfloor \\)得到新的陣列 \\(b\\),接著 \\( \forall{i \in 1 \sim n} \\),將 \\(a_i\\) 搬到 \\(b_i\\),這樣就得到一組解了。
## Exercises
> [CF 1406C Link Cut Centroids](https://codeforces.com/contest/1406/problem/C)
>
> 給你一棵 \\(N\\) 節點的樹,你能刪除樹上的一條邊並且再加入一條邊,使得圖還是一棵樹。> 請問你有沒有辦法讓操作完的樹重心唯一? 請輸出一組可行的操作
> 給你一棵 \\(n\\) 節點的樹,你能刪除樹上的一條邊並且再加入一條邊,使得圖還是一棵樹。
>
> - \\(1 \le N \le 10^5\\)
> 請問你有沒有辦法讓操作完的樹重心唯一? 請輸出一組可行的操作。
>
> - \\(1 \le n \le 10^5\\)
<details><summary> Hint </summary>
Expand All @@ -138,13 +141,13 @@ int main() {
> [CF 685B Kay and Snowflake](https://codeforces.com/problemset/problem/685/B)
>
> 給你一棵 \\(N\\) 節點的有根樹,求每個子樹的重心。
> 給你一棵 \\(n\\) 節點的有根樹,求每個子樹的重心。
>
> - \\(1 \le N \le 3 \times 10^5\\)
> - \\(1 \le n \le 3 \times 10^5\\)
<details><summary> Hint </summary>
在上面找重心的程式碼中,我們每次只會往子樹大小 \\( > \frac{N}{2} \\) 的節點走。
在上面找重心的程式碼中,我們每次只會往子樹大小 \\( > \frac{n}{2} \\) 的節點走。
那我們試著將這個做法反過來,從葉子節點開始,假設現在所在節點為 \\(u\\),\\(u\\) 的父節點為 \\(p\\)。如果 \\( 2 \times size(u) \ge size(p)\\) 的話就繼續往上爬,並把經過的點的重心都設為向上爬的起始點。
Expand Down
4 changes: 2 additions & 2 deletions src/graph/centroid_decomposition.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

## Centroid Decomposition

在詳細介紹重心剖分之前,我們先來介紹一個新名詞—— **重心樹**,它可以幫助我們更好的了解重心剖分的性質。
在詳細介紹重心剖分之前,我們先來介紹一個新名詞 —— **重心樹**,它可以幫助我們更好的了解重心剖分的性質。

### 什麼是重心樹?

Expand Down Expand Up @@ -343,7 +343,7 @@ int main() {

有一點需要稍微注意,如果將這題的查詢改成 **最遠** 的紅色點距離。我們所需要紀錄的資訊就不會這麼簡單了,因為在查詢時可能會遇到這種情況:

假設我們在查詢點 \\(x\\), \\(u\\) 為 \\(x\\) 在重心樹上的祖先,且離 \\(u\\) 最遠的紅色節點為 \\(v\\),所以我們會用 \\(x \rightarrow u \rightarrow v\\) 的距離來更新答案,但如果 \\( LCA'(x, v) \neq u \\),那麼 \\(u\\) 很可能就不在 \\(x\\) 到 \\(v\\) 的路徑上,所以得出來的答案會比正確答案來得 ****
假設我們在查詢點 \\(x\\),\\(u\\) 為 \\(x\\) 在重心樹上的祖先,且離 \\(u\\) 最遠的紅色節點為 \\(v\\),所以我們會用 \\(x \rightarrow u \rightarrow v\\) 的距離來更新答案,但如果 \\( LCA'(x, v) \neq u \\),那麼 \\(u\\) 很可能就不在 \\(x\\) 到 \\(v\\) 的路徑上,所以得出來的答案會比正確答案來得 ****

讀者可以思考一下為什麼這種錯誤不會在求 **最近** 距離的時候發生,而這種情況要怎麼處理會在下一題例題中被提到。

Expand Down

0 comments on commit 138712c

Please sign in to comment.