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