2023年,人類在火星上建立了乙個龐大的基地群,總共有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
輸出檔案僅有乙個正整數,表示至少要設立多少個消防局才有能力及時撲滅任何基地發生的火災。
這道題luogu上給的標籤是dp,嚇了我一跳
但實際上看完,才發現是乙個樹上的貪心
我們以1為根,遍歷整棵樹(只有n-1條邊,所以一定是樹)
然後這道題就變成了乙個可行性問題
如果你想覆蓋掉深度最深的點
你就必須把消防局建在他自己的位置上或者是他父親或者是他爺爺的位置上
如果建在自己的位置上或者說是他父親的位置上,這一定是虧本的
因為他自己深度最深(就是說一定是葉節點),所以不會有兒子之類的
你選他自己或他的父親到會有冗餘覆蓋(覆蓋了不存在的兒子和孫子),一定不是最優
所以我們每次找深度最大的點,在他爺爺那裡建站即可
#include#include#include
#define rii register int i
#define rij register int j
using
namespace
std;
struct
bianx[
1005
];struct
diany[
1005
];int bj[1005],dad[1005],grp[1005
],n,cnt;
void dfs(int wz,int fa,int
gp)//預處理深度和父親,爺爺
y[x[wz].to[i]].sd=y[wz].sd+1
; dfs(x[wz].to[i],wz,fa);
}}void add(int wz,int
sd)
for(rii=1;i<=x[wz].sl;i++)
}bool
cmp(dian lk,dian kl)
intmain()
y[1].sd=1
;
for(rii=1;i<=n;i++)
dfs(
1,0,0
); sort(y+1,y+n+1
,cmp);
for(rii=1;i<=n;i++)
}cout
<}
HNOI2003 消防局的設立
2020年,人類在火星上建立了乙個龐大的基地群,總共有n個基地。起初為了節約材料,人類只修建了n 1條道路來連線這些基地,並且每兩個基地都能夠通過道路到達,所以所有的基地形成了乙個巨大的樹狀結構。如果基地a到基地b至少要經過d條道路的話,我們稱基地a到基地b的距離為d。由於火星上非常乾燥,經常引發火...
HNOI2003 消防局的設立
傳送門 這道題似乎是夾克老爺的憤怒那道題的弱化版 這次的距離是固定為2的。我們首先考慮一下只有一條鏈的情況,這個誰都會,就是每隔2k k為給定距離 個點放乙個,就是這樣貪心。樹也可以用這種貪心法來求解,我們從葉子節點往上dp,每次用dp i 表示這個點還能往上控制距離為多少的點,如果當前的dp值為 ...
HNOI 2003 消防局的設立
題目描述 2020 年,人類在火星上建立了乙個龐大的基地群,總共有 n 個基地。起初為了節約材料,人類只修建了 n 1 條道路來連線這些基地,並且每兩個基地都能夠通過道路到達,所以所有的基地形成了乙個巨大的樹狀結構。如果基地 a 到基地 b 至少要經過 d 條道路的話,我們稱基地 a 到基地 b 的...