2018 09 01 獨立集(樹形dp)

2021-08-26 17:46:43 字數 1878 閱讀 2365

描述

給定一顆樹(邊權為1),選取乙個節點子集,使得該集合中任意兩個節點之間的距離都大於k。求這個集合節點最多是多少

輸入第一行是兩個整數n,k

接下來是n-1行,每行2個整數x,y,表示x與y有一條邊

輸出1個整數表示最多的節點數

樣例輸入

3 1

1 2

1 3樣例輸出

提示測試點

n的上限k特徵

11512

10001鏈

3100014

1000001鏈

510000016

152710002鏈

8100029

1000002鏈

101000002

樹形dp入門題。

t=2的情況有點意思。

設當前訪問第i個節點。 f[

i][0

] f[i

][0]

:i不選但i父親選。 f[

i][1

] f[i

][1]

:不選且i父親不選。 f[

i][2

] f[i

][2]

:i選。

顯然有: f[

i][2

]=1+

∑vf[

v][0

] f[i

][2]

=1+∑

vf[v

][0]

以及: f[

i][0

]=∑v

f[v]

[1] f[i

][0]

=∑vf

[v][

1]

關鍵是f[

i][1

] f[i

][1]

這個東西需要考慮兒子之間是否衝突,因此最優值的產生有兩種可能:

1. 所有兒子都不選。

2. 某乙個兒子選,其餘不選。

因此有f[i

][1]

=(∑v

f[v]

[1])

+max

(0,f

[v][

2]−f

[v][

1]) f[i

][1]

=(∑v

f[v]

[1])

+max

(0,f

[v][

2]−f

[v][

1])。

**:

#include

#define n 100005

using

namespace

std;

inline

int read()

int first[n],n,k,cnt=0,f[n][3];

struct edgee[n<<1];

inline

void add(int u,int v)

inline

int max(int a,int b)

inline

int dfs1(int p,bool k,int fa)

return f[p][k];

}inline

int dfs2(int p,int k,int fa)

}else

if(k==1)

return f[p][k];

}int main()

memset(f,-1,sizeof(f));

if(k==1)cout

<1,1,1),dfs1(1,0,1));

else

cout

<1,1,1),dfs2(1,2,1));

return

0;}

bzoj 4316 小C的獨立集 樹形dp

仙人掌樹形dp。令f x 0 表示以x為根的子樹中,不選x的最大值 f x 1 表示選x的最大值。注意到,同乙個環中的所有點,只有在dfs樹中最高的那個點才會對所在環之外的點的f值造成影響。因此我們在最高的那個點做乙個dp,然後就得到了最高那個點的f,而這個環中的其他點的f就不用管了。ac 如下 i...

樹形DP 樹形DP四例

是時候練一下dp了!我的題單 portkey f u,if fu,i 表示以u uu為根節點的子樹中保留i ii條樹枝的最大蘋果數 f u,i max f max f fu,i max這些題是菜,但也不能輕視啊!include using namespace std define in read i...

HLOJ 樹形DP前置 DFS(樹形DP入門)

給定一棵 n nn 個點的樹,根為 t tt求每個點的父親是哪個點,t tt 的父親輸出 0 00第一行兩個整數 n,t n,tn,t接下來 n 1 n 1n 1 行,每行兩個整數 x,y x,yx,y,表示 x,y x,yx,y 之間有一條邊 n nn 行,第 i ii 行乙個整數,表示 i ii...