zoukankan      html  css  js  c++  java
  • p2279&bzoj1217 消防局的设立

    传送门(洛谷)

    传送门(bzoj)

    题目

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

    Input

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

    Output

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

    Sample Input

    6
    1
    2
    3
    4
    5

    Sample Output

    2

    分析

    一道神仙贪心题(QAQ),我们先随意建一棵树,然后经过分析可以得到这样的贪心策略:

           我们每次找未被消防站覆盖的点中深度最深的点,在这个点的爷爷建消防站,然后将所有可以覆盖的点打标记,直至所有的点都被覆盖。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    struct node{
          int pos,dep;
    }d[1100];
    vector<int>v[1100];
    int fa[1100];
    int chose[1100];
    void dfs(int x,int f){
          int i,j,k;
          d[x].pos=x;
          for(i=0;i<v[x].size();i++)
             if(v[x][i]!=f){
                 fa[v[x][i]]=x;
                 d[v[x][i]].dep=d[x].dep+1;
                 dfs(v[x][i],x);
             }
          return;
    }
    bool cmp(const node &x,const node &y){
          return x.dep>y.dep;
    }
    int main()
    {     int n,m,i,j,k,ans=0;
          cin>>n;
          for(i=1;i<n;i++){
              cin>>k;
              v[k].push_back(i+1);
              v[i+1].push_back(k);
          }
          dfs(1,0);
          sort(d+1,d+n+1,cmp);
          for(i=1;i<=n;i++)
             if(!chose[d[i].pos]){
                 ans++;
                 chose[fa[fa[d[i].pos]]]=1;
                 for(j=0;j<v[fa[fa[d[i].pos]]].size();j++){
                    chose[v[fa[fa[d[i].pos]]][j]]=1;
                    for(k=0;k<v[v[fa[fa[d[i].pos]]][j]].size();k++)
                       chose[v[v[fa[fa[d[i].pos]]][j]][k]]=1;
                 }
             }
          cout<<ans<<endl;
          return 0;
    }

  • 相关阅读:
    vue简单 tabbar封装
    Vue自定义指令实例(实时时间转换指令)
    flutter-搜索条
    flutter-保持页面的效果
    flutter-毛玻璃的效果(很消耗性能)
    flutter-路由跳转动画效果(渐隐渐现,缩放效果,旋转缩放)
    flutter-底部导航&不规则导航
    flutter-异步请求选择回来的方法
    flutter-一般页面导航和返回(传递和接收参数)
    flutter-卡片组件布局
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9026866.html
Copyright © 2011-2022 走看看