zoukankan      html  css  js  c++  java
  • 洛谷 P2279 [HNOI2003]消防局的设立 题解

    每日一题 day34 打卡

    Analysis

    这道题的正解本来是树形dp,但要设5个状态,太麻烦了。于是我就用贪心试图做出此题,没想到还真做出来了。

    考虑当前深度最大的叶子结点,你肯定要有一个消防局去覆盖它,

    那么既然他是叶子结点,所以与他距离小于等于2的节点有这么

    1. 他的父亲 2. 他的兄弟 3. 他的爷爷

    容易看出,在前两项能够覆盖到的节点,在爷爷那里设立一定也能覆盖到。

    所以每次贪心取出深度最大的节点,在他的爷爷哪里放一个消防站

    用STL的priority_queue,时间复杂度O(nlogn)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<vector>
     7 #define int long long
     8 #define R register
     9 #define maxn 1000+10
    10 #define rep(i,s,e) for(register int i=s;i<=e;++i)
    11 using namespace std;
    12 inline int read()
    13 {
    14     int x=0;
    15     bool f=1;
    16     char c=getchar();
    17     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
    18     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    19     if(f) return x;
    20     return 0-x;
    21 }
    22 inline void write(int x)
    23 {
    24     if(x<0){putchar('-');x=-x;}
    25     if(x>9)write(x/10);
    26     putchar(x%10+'0');
    27 }
    28 int n,cnt,ans;
    29 int head[maxn*maxn],dep[maxn],fa[maxn],book[maxn];
    30 struct node
    31 {
    32     int v,nex;
    33 }edge[2*maxn*maxn];
    34 struct cmp
    35 {
    36     bool operator () (int &a,int &b)
    37     {
    38         return dep[a]<dep[b];
    39     } 
    40 };
    41 priority_queue<int,vector<int>,cmp> q;
    42 inline void add(int x,int y)
    43 {
    44     edge[++cnt].v=y;
    45     edge[cnt].nex=head[x];
    46     head[x]=cnt;
    47 }
    48 void calc_deep(int from,int father,int deep)
    49 {
    50     dep[from]=deep;
    51     fa[from]=father;
    52     for(int i=head[from];i;i=edge[i].nex)
    53     {
    54         int to=edge[i].v;
    55         if(to==father) continue;
    56         calc_deep(to,from,deep+1);
    57     }
    58 }
    59 void update(int from,int wide)
    60 {
    61     if(wide>2) return;
    62     book[from]=1;
    63     for(int i=head[from];i;i=edge[i].nex)
    64     {
    65         int to=edge[i].v;
    66         update(to,wide+1);
    67     }
    68 }
    69 signed main()
    70 {
    71     n=read();
    72     rep(i,1,n-1) 
    73     {
    74         int x=read();
    75         add(i+1,x);add(x,i+1);
    76     }
    77     calc_deep(1,0,1);
    78     rep(i,1,n) q.push(i);
    79     while(!q.empty())
    80     {
    81         while(!q.empty()&&book[q.top()]==1) q.pop();
    82         if(q.empty()==1) break;
    83         if(fa[fa[q.top()]]==0) update(1,0);
    84         else if(fa[fa[q.top()]]>0) update(fa[fa[q.top()]],0);
    85         ans++;
    86     }
    87     write(ans);
    88     return 0;
    89 }

    请各位大佬斧正(反正我不认识斧正是什么意思)

  • 相关阅读:
    POJ3662 Telephone Lines (dijkstra+二分)
    Codeforces Round #618 (Div. 2)A. Non-zero
    Codeforces Round #618 (Div. 2)C. Anu Has a Function
    洛谷P1060开心的金明(滚动数组优化)
    洛谷P1006传纸条
    Spring Boot中以代码方式配置Tomcat
    js常用方法总结(以后遇到再进一步总结)
    localStorage的使用
    巧用Ajax的beforeSend 提高用户体验
    四种会话跟踪技术
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/11837366.html
Copyright © 2011-2022 走看看