1. 程式人生 > >luogu HNOI2003消防局的設立

luogu HNOI2003消防局的設立

dfs margin lap char closed alt src 方程 ccf

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]<i。

輸出格式:

輸出文件名為output.txt

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

樹形dp沒推出轉移方程,兩遍dfs打了貪心

技術分享圖片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1e5+5;
  4 const int INF=1e9+5;
  5 int n,a,b,maxx,mark;
  6 int ans,x,d[maxn],f[maxn];
  7 bool vis[maxn];
  8
int head[maxn],tot; 9 struct A 10 { 11 int v,next; 12 }e[maxn]; 13 template <class t>void red(t &x) 14 { 15 x=0; 16 int w=1; 17 char ch=getchar(); 18 while(ch<0||ch>9) 19 { 20 if(ch==-) 21 w=-1; 22 ch=getchar();
23 } 24 while(ch>=0&&ch<=9) 25 { 26 x=(x<<3)+(x<<1)+ch-0; 27 ch=getchar(); 28 } 29 x*=w; 30 } 31 void input() 32 { 33 freopen("input.txt","r",stdin); 34 //freopen("output.txt","w",stdout); 35 } 36 struct cmp{ 37 bool operator () (int &a,int &b){ 38 return d[a]<d[b]; 39 } 40 }; 41 priority_queue<int,vector<int>,cmp> q; 42 void add(int x,int y) 43 { 44 e[++tot].v=y; 45 e[tot].next=head[x]; 46 head[x]=tot; 47 } 48 void read() 49 { 50 red(n); 51 for(int i=2;i<=n;++i) 52 { 53 red(a); 54 add(a,i); 55 add(i,a); 56 } 57 } 58 void dfs1(int u,int fa) 59 { 60 d[u]=d[fa]+1; 61 for(int i=head[u];i;i=e[i].next) 62 { 63 int v=e[i].v; 64 if(v==fa) 65 continue; 66 f[v]=u; 67 dfs1(v,u); 68 } 69 } 70 void dfs2(int u,int dep) 71 { 72 if(dep>2) 73 return; 74 vis[u]=1; 75 for(int i=head[u];i;i=e[i].next) 76 { 77 int v=e[i].v; 78 dfs2(v,dep+1); 79 } 80 } 81 void work() 82 { 83 dfs1(1,0); 84 for(int i=1;i<=n;++i) 85 if(d[i]>maxx) 86 { 87 maxx=d[i]; 88 mark=i; 89 } 90 for(int i=1;i<=n;++i) 91 q.push(i); 92 while(!q.empty()) 93 { 94 while(!q.empty()&&vis[x=q.top()]) 95 q.pop(); 96 if(q.empty()) 97 break; 98 if(f[f[x]]) 99 dfs2(f[f[x]],0); 100 else 101 dfs2(1,0); 102 ++ans; 103 } 104 printf("%d",ans); 105 } 106 int main() 107 { 108 //input(); 109 read(); 110 work(); 111 return 0; 112 }
View Code

luogu HNOI2003消防局的設立