P3174 HAOI2009 毛毛蟲 題解

2021-10-04 19:24:32 字數 2626 閱讀 4800

同步

原題鏈結

簡要題意:

給定一棵樹,求最長的 「掛鏈」 長度。

掛鏈定義為:一條鏈上所有節點與其相連的節點構成的生成樹。(非嚴謹定義)(原題中是 「毛毛蟲」,本人以為掛鏈更形象)

這題有多種做法,這裡給出思路,以及其中一種做法的**。

注意到,其實我們只需要選出 「最長鏈」,然後在最長鏈的兩側掛鏈即可。

即,先求出樹的直徑的兩個端點,然後遍歷一遍直徑上的端點,把它們的直接連邊都加入生成樹中。

最後統計答案即可。

時間複雜度:o(n

)o(n)

o(n)

.期望得分:100pt

s100pts

100pts

.考慮樹形 dp

\text

dp,用 f

if_i

fi​ 表示以 i

ii 為根的最大掛鏈長度,sub

isub_i

subi

​ 記錄 i

ii 的兒子個數,則:

f u=

max⁡(f

v,fv

+sub

u−1)

(v

∈son⁡(

u)

)f_u = \max(f_v , f_v + sub_u - 1) (v \in \operatorname (u))

fu​=

max(fv

​,fv

​+su

bu​−

1)(v

∈son

(u))

很顯然,要麼直接繼承兒子節點的答案,要麼把兩邊一拼。

時間複雜度:o(n

)o(n)

o(n)

.期望得分:100pt

s100pts

100pts

.給出乙個最巧妙的演算法。

假設 i

ii 號點的度是 a

ia_i

ai​,則一條長度為 s

ss 的掛鏈的答案應該是:

( ∑i

∈list⁡a

i)−(

s−1)

+1

\bigg ( \sum_} a_i \bigg ) -(s-1) + 1

(i∈lis

t∑​a

i​)−

(s−1

)+1i

∈list

⁡i \in \operatorname

i∈list

表示 i

ii 屬於當前鏈,s−1

s-1s−

1 即把重複計算的邊去掉得到邊數,然後 +1+1

+1得到點數。化簡即:

= (∑

i∈

list⁡a

i)−s

+2

= \bigg ( \sum_ } a_i \bigg ) - s + 2

=(i∈li

st∑​

ai​)

−s+2

你發現這個東西有點難看,於是換了一下:

= ∑i

∈list⁡(

ai−1

)+

2=\sum_ } (a_i - 1) + 2

=i∈lis

t∑​(

ai​−

1)+2

顯然,把 s

ss 減到每個節點裡面 ,每個點分 1

11 個。

那麼我們可以按照如下步驟求解:

建圖統計度,並將度 −1-1

−1.求出直徑兩端。

統計直徑上所有節點的度,然後 +2+2

+2即為答案。

時間複雜度:o(n

)o(n)

o(n)

.實際得分:100pt

s100pts

100pts

.

#pragma gcc optimize(2)

#include

using

namespace std;

const

int n=

3e5+1;

inline

intread()

int x=0;

while

(isdigit

(ch)

) x=x*

10+ch-

'0',ch=

getchar()

;return x*f;

}int n,m,du[n]

,dis[n]

;int num,mx;

vector<

int> g[n]

;inline

void

dfs(

int dep,

int fa,

int dis)

intmain()

dfs(1,

0,du[1]

); mx=0;

dfs(num,

0,du[num]);

//兩次 dfs 尋找直徑

printf

("%d\n"

,mx+2)

;// +2 就是答案

return0;

}

HAOI2009 毛毛蟲 樹形dp

試題描述 對於一棵樹,我們可以將某條鏈和與該鏈相連的邊抽出來,看上去就象成乙個毛毛蟲,點數越多,毛毛蟲就越大。例如下圖左邊的樹 圖 1 抽出一部分就變成了右邊的乙個毛毛蟲了 圖 2 輸入資料 在文字檔案 worm.in 中第一行兩個整數 n m 分別表示樹中結點個數和樹的邊數。接下來 m 行,每行兩...

HAOI2009 毛毛蟲 樹形DP

題意 給你一棵樹,從樹中取出一部分滿足 是一條鏈 一些直接連在這條鏈上的節點 求節點數最多的合法取出部分。題解 其實這題還是不難?觀察到對於任意一條鏈,只有兩種情況 一條路走到底 or 以某個點為中轉 f x 表示從x往下走,一路走到底的包括x的最優解,f x 包括x也包括father x 將會加入...

haoi2009 毛毛蟲 樹形dp

這道題細節處理不少,但要ac不難 設以i節點為根節點的子樹能形成的最大的毛毛蟲長度為f i 則f i max f j i節點的孩子數 答案需要f最大和次大的兩個子樹合併,而且若合併的位置不是根節點,ans 我就是坑在了最後一點上,最後打表找到了問題 1 include2 include3 inclu...