• bzoj1217: [HNOI2003]消防局的设立 [树形dp]


    Description

    2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地。起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状结构。如果基地A到基地B至少要经过d条道路的话,我们称基地A到基地B的距离为d。由于火星上非常干燥,经常引发火灾,人类决定在火星上修建若干个消防局。消防局只能修建在基地里,每个消防局有能力扑灭与它距离不超过2的基地的火灾。你的任务是计算至少要修建多少个消防局才能够确保火星上所有的基地在发生火灾时,消防队有能力及时扑灭火灾。

    Input

    输入文件的第一行为n,表示火星上基地的数目。接下来的n-1行每行有一个正整数,其中文件第i行的正整数为a[i],表示从编号为i的基地到编号为a[i]的基地之间有一条道路,为了更加简洁的描述树状结构的基地群,有a[i]

    Output

    输出文件仅有一个正整数,表示至少要设立多少个消防局才有能力及时扑灭任何基地发生的火灾。

    Sample Input

    6
    1
    2
    3
    4
    5

    Sample Output

    2

    论状态设计之巧妙
     1 /**************************************************************
     2     Problem: 1217
     3     User: ZYBGMZL
     4     Language: C++
     5     Result: Accepted
     6     Time:0 ms
     7     Memory:1312 kb
     8 ****************************************************************/
     9  
    10 #include<cstdio>
    11 #include<cstring>
    12 #include<iostream>
    13 using namespace std;
    14 #define inf 0x3f3f3f3f
    15  
    16 struct Edge{
    17     int to,nxt;
    18     Edge(int to=0,int nxt=0):
    19         to(to),nxt(nxt){}
    20 };
    21  
    22 const int maxn=1005;
    23  
    24 int n,cnt=0,ans=0,f[maxn],head[maxn];
    25 Edge E[maxn<<1];
    26  
    27 inline void a_ed(int from,int to){
    28     E[++cnt]=Edge(to,head[from]);  head[from]=cnt;
    29     E[++cnt]=Edge(from,head[to]);  head[to]=cnt;
    30 }
    31  
    32 void dfs(int no,int fa){
    33     int mx=-inf,mi=inf;
    34     for(int e=head[no];e;e=E[e].nxt){
    35         int nt=E[e].to;  if(nt==fa)  continue;
    36         dfs(nt,no);
    37         mx=max(mx,f[nt]);  mi=min(mi,f[nt]);
    38     }
    39     if(mx+mi<=3)  f[no]=mi+1;
    40     else  f[no]=mx+1;
    41     if(mx==-inf)  f[no]=3;
    42     if(f[no]==5){
    43         f[no]=0;
    44         ans++;
    45     }
    46     if(f[no]>=3&&fa==-1)  ans++;
    47 }
    48  
    49 int main(){
    50     scanf("%d",&n);
    51     for(int i=2,to;i<=n;i++){
    52         scanf("%d",&to);
    53         a_ed(i,to);
    54     }
    55     dfs(1,-1);
    56     printf("%d
    ",ans);
    57     return 0;
    58 }
  • 相关阅读:
    Java 并发工具包 java.util.concurrent 用户指南
    Java 序列化Serializable详解(附详细例子)
    Spring之FactoryBean .
    《用chsh选择shell》-linux命令五分钟系列之十二
    《vi中的替换艺术》-linux命令五分钟系列之十一
    0-1背包问题
    Java关键字final、static使用总结
    《作业控制系列》-“linux命令五分钟系列”之十
    《zip命令》-linux命令五分钟系列之九
    《bunzip2命令》-linux命令五分钟系列之八
  • 原文地址:https://www.cnblogs.com/ZYBGMZL/p/7296069.html
Copyright © 2020-2023  润新知