P2016 戰略遊戲

2021-09-26 15:44:31 字數 1627 閱讀 6655

樹形dp

f [u

][0]

表示

uf[u][0]表示u

f[u][0

]表示u

號節點不放士兵,以x為根的子樹需要的最少士兵數。

f [u

][1]

表示

uf[u][1]表示u

f[u][1

]表示u

號節點放士兵,以x為根的子樹需要的最少士兵數。

由於我們定義的是將其完全覆蓋,則我們不需要考慮父親節點,為什麼?

當我們已經回到u

uu的父親節點時(設u

uu的父親為x

xx),我們已經算出覆蓋u

uu這棵子樹的最小代價了,所以我們只需要看u

uu的父親節點放還是不放就行了,如果不放,則加上f[u

][1]

f[u][1]

f[u][1

],如果放加上min

(f[u

][1]

,f[u

][0]

)min(f[u][1],f[u][0])

min(f[

u][1

],f[

u][0

])為什麼只需要設當前節點放不放和當前節點的兒子放不放兩種狀態,因為在求當前節點放不放時,至於當前節點的這條邊有關,而他的父親節點是管不到這兒來的

f[u

][0/

1]均已

經求出!

!!

!f[u][0/1]均已經求出!!!!

f[u][0

/1]均

已經求出

!!!!

#include

#define rep(i,a,b) for(register int (i)=(a);(i)<=(b);(i)++)

#define don(i,a,b) for(register int (i)=(a);(i)>=(b);(i)--)

using

namespace std;

const

int maxn=

2e5+10;

const

int maxm=

1e3+10;

int n,cnt;

int head[maxn]

,f[maxn][2

];template

<

class

t>

inline

void

read

(t &x)

while

(isdigit

(ch)

) x*

=f;}

struct nodee[maxn<<1]

;void

add(

int u,

int v)

void

readdata()

}}void

dfs(

int u,

int fa)

}void

work()

intmain()

P2016 戰略遊戲

題面 題目背景 bob 喜歡玩電腦遊戲,特別是戰略遊戲。但是他經常無法找到快速玩過遊戲的辦法。現在他有個問題。題目描述 他要建立乙個古城堡,城堡中的路形成一棵無根樹。他要在這棵樹的結點上放置最少數目的士兵,使得這些士兵能瞭望到所有的路。注意,某個士兵在乙個結點上時,與該結點相連的所有邊將都可以被瞭望...

題解 P2016 戰略遊戲

題目 解法跟 dalao real ljs 類似,但沒有用到遞迴 題目相當於需要求覆蓋這顆樹需要的最小點數 用 dp 表示在這棵樹中,以 i 為根節點的子樹在選 不選根節點的情況下,覆蓋這棵樹所有邊需要的最小點數 所以,當不選這個節點 i 時,則所有 以其子節點為根節點的子樹 都必選根節點 當選擇這...

洛谷 P2016 戰略遊戲

題目描述 bob喜歡玩電腦遊戲,特別是戰略遊戲。但是他經常無法找到快速玩過遊戲的辦法。現在他有個問題。他要建立乙個古城堡,城堡中的路形成一棵樹。他要在這棵樹的結點上放置最少數目的士兵,使得這些士兵能瞭望到所有的路。注意,某個士兵在乙個結點上時,與該結點相連的所有邊將都可以被瞭望到。請你編一程式,給定...