AcWing 1077 皇宮看守

2021-10-19 02:04:54 字數 1988 閱讀 3042

和acwing 323. 戰略遊戲這題非常類似,但又有些不同

acwing 323. 戰略遊戲在一條道路的兩個結點至少有乙個是放的,而這題不一定,比如

1

/ | \

2 3 4

/ |5 6

我們可以在3,4,5,6號點放,其他各點都不放。這樣邊1-2的兩個端點都沒有守衛,這就和acwing 323. 戰略遊戲這題不同了

不過稍微觀察可以發現,acwing 323. 戰略遊戲這題的切入點是邊,而本題的切入點是宮殿,也就是樹上的結點。那麼可以用再在不放這個狀態上增加乙個狀態,即

有了狀態表示,接下來j就是推導狀態轉移了,記j為u的子結點,那麼

f [u

][0]

=∑j=

0umi

nf[u][0] = \sum_^u min \lbrace f[j][1], f[j][2]\rbrace

f[u][0

]=∑j

=0u​

min。含義:當前結點u不放且被父節點看到,那麼子結點j只能放或者被其子結點看到。因為u不放所以不能拿f[j][0]來更新

f [u

][1]

=f[k

][2]

+∑mi

nf[u][1] = f[k][2] + \sum min \lbrace f[j][1], f[j][2]\rbrace

f[u][1

]=f[

k][2

]+∑m

in。含義:當前結點u不放,u的子結點k放了,u的其他子結點j放(f[j][2])或者不放(即f[j][1])。沒有f[j][0]的原因也是因為u不放,且需要列舉k。

f [u

][2]

=∑j=

0umi

nf[u][2] = \sum_^u min \lbrace f[j][0], f[j][1], f[j][2]\rbrace

f[u][2

]=∑j

=0u​

min。含義:當前結點放了,那麼子結點取哪種狀態都可以

1,3實現起來比較容易,至於2的實現,詳情見**注釋

#include

#include

using

namespace std;

const

int n =

1510

;int h[n]

, e[n + n]

, ne[n + n]

, idx;

int n, w[n]

;int f[n][3

];void

add(

int a,

int b)

void

dfs(

int u,

int father)

f[u][1

]=1e9;

//依次假設每個結點放, sum - min(f[j][1], f[j][2])就是其他所有結點的放和不放最小值之和

//我們很驚奇地發現,f[u][0]就已經計算過了這個sum,可以拿f[u][0]來代替sum,但為了語義明確,使用sum來表示更合理

for(

int i = h[u]

;~i; i = ne[i])}

intmain()

}//建立雙向邊,從任意乙個結點開始

dfs(1,

0); cout <<

min(f[1]

[1], f[1]

[2])

<< endl;

return0;

}

Acwing 1077 皇宮看守

題目描述 太平王世子事件後,陸小鳳成了皇上特聘的御前一品侍衛。皇宮各個宮殿的分布,呈一棵樹的形狀,宮殿可視為樹中結點,兩個宮殿之間如果存在道路直接相連,則該道路視為樹中的一條邊。已知,在乙個宮殿鎮守的守衛不僅能夠觀察到本宮殿的狀況,還能觀察到與該宮殿直接存在道路相連的其他宮殿的狀況。大內保衛森嚴,三...

ACWing 1077 皇宮看守

太平王世子事件後,陸小鳳成了皇上特聘的御前一品侍衛。皇宮各個宮殿的分布,呈一棵樹的形狀,宮殿可視為樹中結點,兩個宮殿之間如果存在道路直接相連,則該道路視為樹中的一條邊。已知,在乙個宮殿鎮守的守衛不僅能夠觀察到本宮殿的狀況,還能觀察到與該宮殿直接存在道路相連的其他宮殿的狀況。大內保衛森嚴,三步一崗,五...

AcWing 1077 皇宮看守

原題鏈結 考察 樹形dp 這道題戰略遊戲要求看到所有的邊,本題要求看到所有的點 沒想出來,參考了大佬的思路 照搬大佬的思路 設樹上某點u能被看見,這個點要麼自己安插士兵,要麼父節點安插士兵,要麼子節點安插士兵.設f u,st 表示u的st狀態的最小花費.st 0時,它u被父節點看見,st 1,u被子...