• F


    题目链接:

    F - Auxiliary Set

     HDU - 5927 

    学习网址:https://blog.csdn.net/yiqzq/article/details/81952369
    题目大意一棵节点数为n的有根数,根节点为1,一开始所有的点都是重点,接下来有q次询问,每次询问把m个点变为轻点,问你树中还有多少个重点。 
    重点应该满足的条件为: 
    1.它本身是重点。 
    2.它为两个重点的最近公共祖先。 
    每次询问之后在下次询问前,所有的点都恢复为重点。

    具体思路:对于每个点保存他的深度。因为每次输入的数不重要的点,首先对于这些不重要的点按照深度从大到小进行排序, 然后先去处理深度大的。当处理深度大的时候,可以保证这个节点下面是没有不重要的点的,也就是这个节点的下面全都是重要的节点,那么这个点也肯定是符合的。然后往上更新的时候,如果当前的不重要节点下面没有点了,那么这个不重要节点的父亲往下的儿子数就应该减去1,也就是说这个分支下不存在重要的节点了。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define ll long long
     4 const int maxn = 2e5+100;
     5 int n,m;
     6 vector<int>edge[maxn];
     7 void addedge(int fr,int to)
     8 {
     9     edge[fr].push_back(to);
    10 }
    11 int sto[maxn];
    12 int depth[maxn];
    13 int son1[maxn],son2[maxn];
    14 int father[maxn];
    15 void init()
    16 {
    17     for(int i=1; i<=n; i++)
    18     {
    19         edge[i].clear();
    20         son1[i]=0;
    21     }
    22 }
    23 void dfs(int cur,int fa,int dep)
    24 {
    25     father[cur]=fa;
    26     depth[cur]=dep+1;
    27     for(int i=0; i<edge[cur].size(); i++)
    28     {
    29         int to=edge[cur][i];
    30         if(to==fa)
    31             continue;
    32            son1[cur]++;
    33           dfs(to,cur,dep+1);
    34     }
    35 }
    36 bool cmp(int t1,int t2)
    37 {
    38     return depth[t1]>depth[t2];
    39 }
    40 int main()
    41 {
    42     int T;
    43     int Case=0;
    44     scanf("%d",&T);
    45     while(T--)
    46     {
    47         int st,ed;
    48         scanf("%d %d",&n,&m);
    49         init();
    50         for(int i=1; i<n; i++)
    51         {
    52             scanf("%d %d",&st,&ed);
    53             addedge(st,ed);
    54             addedge(ed,st);
    55         }
    56         printf("Case #%d:
    ",++Case);
    57         dfs(1,0,0);
    58         while(m--)
    59         {
    60             int sz,ans;
    61             scanf("%d",&sz);
    62             ans=n-sz;
    63             for(int i=1; i<=sz; i++)
    64             {
    65                 scanf("%d",&sto[i]);
    66                 son2[sto[i]]=son1[sto[i]];
    67             }
    68             sort(sto+1,sto+sz+1,cmp);
    69             for(int i=1; i<=sz; i++)
    70             {
    71                 if(son2[sto[i]]>=2)
    72                     ans++;
    73                 if(son2[sto[i]]==0)
    74                     son2[father[sto[i]]]--;
    75             }
    76             printf("%d
    ",ans);
    77         }
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    设计模式之单例模式
    Java的8种基本数据类型的内存占用字节数和取值范围
    如何解析本地和线上XML文件获取相应的内容
    Android性能优化(一)之启动加速35%
    自定义控件?试试300行代码实现QQ侧滑菜单
    菜单开源库装逼大全
    View动画和属性动画
    第三方分享
    Android 谈谈封装那些事 --BaseActivity 和 BaseFragment(二)
    转:工具类之SpannableStringUtils(相信你会爱上它)
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10704167.html
Copyright © 2020-2023  润新知