2020 年,人類在火星上建立了乙個龐大的基地群,總共有 n 個基地。起初為了節約材料,人類只修建了 n-1 條長為 1 的道路來連線這些基地,並且每兩個基地都能夠通過道路到達,所以所有的基地形成了乙個巨大的樹狀結構。
由於火星上非常乾燥,經常引發火災,人類決定在火星上修建若干個消防局。消防局只能修建在基地裡,每個消防局有能力撲滅與它距離不超過 2 的基地的火災。
你的任務是計算至少要修建多少個消防局才能夠確保火星上所有的基地在發生火災時,消防隊有能力及時撲滅火災。
輸入檔案的第一行為 n,表示火星上基地的數目。
接下來的 n-1 行每行有乙個正整數,其中檔案第 i 行的正整數為 ai,表示從編號為 i 的基地到編號為 a1 的基地之間有一條道路,為了更加簡潔的描述樹狀結構的基地群,有 ai < i。
輸出檔案僅有乙個正整數,表示至少要設立多少個消防局才有能力及時撲滅任何基地發生的火災。
這是一道稍複雜的樹形dp,對於每個點,我定義了5個狀態,分別為dp[ i ][ 1 ~ 5 ],表示為 i 點提供消防服務的是 i 的①爺爺/兄弟、②父親、③自己、④乙個兒子、⑤乙個孫子。
具體這樣計算:
dfs(int x)
dp[x][4] += ***1;
dp[x][5] += ***2;
}
可見此題的狀態轉移方程很複雜。
#include#include#include#include#include#include#define ll long long
using namespace std;
ll read()
while(s >= '0' && s <= '9')
return x * f;
}//讀入優化
ll n,m,i,j,s,o,k;
vectorg[1005];//樹
int dp[1005][10];
ll min(ll a,ll b)
void dfs(int x,int fa)
} dp[x][4] += ***1;
dp[x][5] += ***2;
return ;
}int main()
dfs(1,0);
printf("%d\n",min(dp[1][3],min(dp[1][4],dp[1][5])));
return 0;
}
消防局的設立
我先想的是貪心,但是沒有任何依據 所以rang了 然後想到了乙個有依據的貪心 我們可以找深度最深的乙個點開始考慮。可以證明,取此節點的爺爺一定是最優的。取自己 可以覆蓋自己,自己兄弟,父親,爺爺。取兄弟 可以覆蓋自己,自己兄弟,父親,爺爺。取父親 可以覆蓋自己,自己兄弟,父親,爺爺,父親的兄弟。取爺...
消防局的設立
p2279 hnoi2003 消防局的設立 主要思路 貪心,從葉子節點開始 按深度排序即可做到 從它父親的父親,把距離不超過 2 的節點都打上標記,ans 這樣一定最優,因為必須覆蓋那個沒被覆蓋的節點,而從祖父開始可以覆蓋更多的點。注意把根節點的父親設為根節點,否則從根節點開始跳就re了 inclu...
消防局的設立(樹形DP)
2020 年,人類在火星上建立了乙個龐大的基地群,總共有 n 個基地。起初為了節約材料,人類只修建了 n 1 條長為 1 的道路來連線這些基地,並且每兩個基地都能夠通過道路到達,所以所有的基地形成了乙個巨大的樹狀結構。由於火星上非常乾燥,經常引發火災,人類決定在火星上修建若干個消防局。消防局只能修建...