zoukankan      html  css  js  c++  java
  • luogu2279 消防局的设立 (贪心)

    按点的深度从大到小排序,每次取出深度最大的那个点,如果它还没被覆盖,就在它爷爷上放一个消防局,这样一定是最优的

    为了判定是否被覆盖,可以记录从某点的子树中到这个点的最近消防局的距离dis[](如果没有就是inf呗)

    这样的话,对于x,如果dis[x]<=2或者dis[fa[x]]<=1或者dis[fa[fa[x]]]<=0,他就已经被覆盖了,直接跳过

    用这种方法,可以做覆盖范围更大的

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define CLR(a,x) memset(a,x,sizeof(a))
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=1010,inf=1e9;
     7 
     8 inline ll rd(){
     9     ll x=0;char c=getchar();int neg=1;
    10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    12     return x*neg;
    13 }
    14 
    15 int N,md[maxn],fa[maxn],dep[maxn],id[maxn];
    16 
    17 inline bool cmp(int x,int y){return dep[x]>dep[y];}
    18 
    19 int main(){
    20     //freopen("","r",stdin);
    21     int i,j,k;
    22     N=rd();
    23     dep[1]=id[1]=1;md[1]=inf;
    24     for(i=2;i<=N;i++){
    25         fa[i]=rd();id[i]=i;
    26         md[i]=inf;
    27         dep[i]=dep[fa[i]]+1;
    28     }
    29     sort(id+1,id+N+1,cmp);
    30     int ans=0;
    31     for(i=1;i<=N;i++){
    32         int x=id[i];
    33         if(md[x]<=2||(fa[x]&&(md[fa[x]]<=1||(fa[fa[x]]&&md[fa[fa[x]]]<=0)))) continue;
    34         int f=fa[x]?(fa[fa[x]]?fa[fa[x]]:fa[x]):x;
    35         md[f]=0;
    36         ans++;
    37         if(fa[f]){
    38             md[fa[f]]=min(md[fa[f]],1);
    39             if(fa[fa[f]])
    40                 md[fa[fa[f]]]=min(md[fa[fa[f]]],2);
    41         }
    42     }
    43     printf("%d
    ",ans);
    44     return 0;
    45 }
  • 相关阅读:
    echo和tee的使用
    cut列的截取
    BZOJ1414: [ZJOI2009]对称的正方形(二维hash)
    BZOJ1010: [HNOI2008]玩具装箱toy
    BZOJ2588: Spoj 10628. Count on a tree(主席树)
    BZOJ3991: [SDOI2015]寻宝游戏(set+lca / 虚树)
    BZOJ2286: [Sdoi2011]消耗战(虚树)
    Linux
    奇妙的棋盘(建图+搜索)
    礼物(动态规划)
  • 原文地址:https://www.cnblogs.com/Ressed/p/9811142.html
Copyright © 2011-2022 走看看