Luogu2279[HNOI2003] 消防局的設立

原題鏈接:https://www.luogu.org/problemnew/show/P2279

消防局的設立

題目描述

20202020年,人類在火星上建立了一個龐大的基地羣,總共有nn個基地。起初爲了節約材料,人類只修建了n1n-1條道路來連接這些基地,並且每兩個基地都能夠通過道路到達,所以所有的基地形成了一個巨大的樹狀結構。如果基地AA到基地BB至少要經過dd條道路的話,我們稱基地AA到基地BB的距離爲dd

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

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

輸入輸出格式
輸入格式:

輸入文件名爲input.txtinput.txt

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

輸出格式:

輸出文件名爲output.txtoutput.txt

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

輸入輸出樣例
輸入樣例#1:

6
1
2
3
4
5

輸出樣例#1:

2

題解

貪心策略:每次都找到深度最深的沒被覆蓋的點,在它的爺爺設立消防站,這樣決策沒有後效性,也是當前能做出的最優決策。

所以我們把每個點按深度排序,記錄每個點離最近的消防站的距離,當距離大於22時在他爺爺設立消防站並更新爺爺的爸爸和爺爺的距離。

代碼
#include<bits/stdc++.h>
using namespace std;
const int M=1005;
int dad[M],dep[M],pt[M],dis[M],n,ans;
bool cmp(int a,int b){return dep[a]>dep[b];}
void in()
{
    scanf("%d",&n);pt[1]=1,dis[0]=dis[1]=M;
    for(int i=2;i<=n;++i)scanf("%d",&dad[i]),dep[i]=dep[dad[i]]+1,pt[i]=i,dis[i]=M;
}
void ac()
{
    sort(pt+1,pt+1+n,cmp);
    for(int i=1,v,f,ff;i<=n;++i)
    {
        v=pt[i],f=dad[v],ff=dad[f];
        dis[v]=min(dis[v],min(dis[f]+1,dis[ff]+2));
        if(dis[v]>2)dis[ff]=0,++ans,dis[dad[ff]]=min(dis[dad[ff]],1),dis[dad[dad[ff]]]=min(dis[dad[dad[ff]]],2);
    }
    printf("%d",ans);
}
int main(){in(),ac();}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章