HNOI 2003 消防局的設立

2022-05-31 08:06:15 字數 2020 閱讀 6005

題目描述

2020 年,人類在火星上建立了乙個龐大的基地群,總共有 n 個基地。起初為了節約材料,人類只修建了 n-1 條道路來連線這些基地,並且每兩個基地都能夠通過道路到達,所以所有的基地形成了乙個巨大的樹狀結構。如果基地 a 到基地 b 至少要經過 d 條道路的話,我們稱基地 a 到基地 b 的距離為 d。

由於火星上非常乾燥,經常引發火災,人類決定在火星上修建若干個消防局。消防局只能修建在基地裡,每個消防局有能力撲滅與它距離不超過 2 的基地的火災。

你的任務是計算至少要修建多少個消防局才能夠確保火星上所有的基地在發生火災時,消防隊有能力及時撲滅火災。

輸入輸出格式

輸入格式:

輸入檔名為 input.txt。

輸入檔案的第一行為 n (n<=1000),表示火星上基地的數目。接下來的 n-1 行每行有乙個正整數,其中檔案第 i 行的正整數為 a[i],表示從編號為 i 的基地到編號為 a[i] 的基地之間有一條道路,為了更加簡潔的描述樹狀結構的基地群,有a[

i]輸出格式:

輸出檔名為 output.txt

輸出檔案僅有乙個正整數,表示至少要設立多少個消防局才有能力及時撲滅任何基地發生的火災。

輸入輸出樣例

輸入樣例 #1:

6 1

2 3

4 5

輸出樣例 #1:

2很有意思的一道(shui)題,但是對於某蒟蒻來說,也是想了很久。。。t_t

樹形 dp,就是 dfs+ 向上更新。比較難想到的是狀態,這裡每種節點用了 5 個 dp[v][0~4],分別代表某個節點 v** 至少覆蓋到孫子、兒子、自己、父親、祖父節點 ** 所需的消防站個數。

然後是狀態轉移。從覆蓋到祖父開始,很容易看出來,這個節點 v 自己一定要塗色(設消防局),向上兩個距離,向下兩個距離,所以 v 的兒子們只要管到各自的孫子就行了。畫張圖理解下:

如果要求覆蓋到父親,那麼一種情況就是同上,因為這 5 種狀態是包含的關係,而不是排斥的。第二種情況,就是 v 的某個兒子覆蓋到它的祖父(一起唱:兒子的爺爺是爸爸),由於那個兒子可以向上兩個距離,同時也可以繞下來覆蓋 v 的其他的兒子節點,從而 v 的其他兒子只要管到各自的兒子就行了。

如果要求覆蓋到自己,第一種情況也包含在上面。第二種情況,v 的某個兒子覆蓋到 v(就是他的父親),其餘的兒子管到自身。

之後的以此類推←_←具體見**

#include 

#include

#include

using

namespace

std;

const

int maxn = 3000, inf = 0x3f3f3f3f;

int head[maxn], next[maxn], to[maxn], pa[maxn], tot, n;

bool lf[maxn]; //是否為葉子節點

int dp[maxn][10]; //樹狀dp

//dp[v][n] = 從n=0時為v的孫子節點,到n=4時為v的祖父節點,覆蓋到第n層所需的最少數目

void init()

void add2(int a, int b)

void pushup(int v)

}dp[v][3] = dp[v][0] + min1;

dp[v][2] = dp[v][1] + min2;

for(int i = 3; i >= 0; --i)

}void dfs(int v)

for(int i = head[v]; ~i; i = next[i])

}pushup(v);

}int main()

init();

for(int i = 2; i <= n; ++i)

dfs(1);

printf("%d\n", dp[1][2]);

return

0;}

HNOI2003 消防局的設立

2020年,人類在火星上建立了乙個龐大的基地群,總共有n個基地。起初為了節約材料,人類只修建了n 1條道路來連線這些基地,並且每兩個基地都能夠通過道路到達,所以所有的基地形成了乙個巨大的樹狀結構。如果基地a到基地b至少要經過d條道路的話,我們稱基地a到基地b的距離為d。由於火星上非常乾燥,經常引發火...

HNOI2003 消防局的設立

2020年,人類在火星上建立了乙個龐大的基地群,總共有n個基地。起初為了節約材料,人類只修建了n 1條道路來連線這些基地,並且每兩個基地都能夠通過道路到達,所以所有的基地形成了乙個巨大的樹狀結構。如果基地a到基地b至少要經過d條道路的話,我們稱基地a到基地b的距離為d。由於火星上非常乾燥,經常引發火...

HNOI2003 消防局的設立

傳送門 這道題似乎是夾克老爺的憤怒那道題的弱化版 這次的距離是固定為2的。我們首先考慮一下只有一條鏈的情況,這個誰都會,就是每隔2k k為給定距離 個點放乙個,就是這樣貪心。樹也可以用這種貪心法來求解,我們從葉子節點往上dp,每次用dp i 表示這個點還能往上控制距離為多少的點,如果當前的dp值為 ...