zoukankan      html  css  js  c++  java
  • CF796C Bank Hacking

     

     

    题意:给定一棵树,每个节点上有一个银行,最初所有银行全部在线,有一只狗想要打下所有银行(没错是狗),每个银行都有一个安全值,狗的电脑的值必须大于等于所攻下银行的安全值,且每打下一个银行后和它距离为1和2的点的安全值都会在原来的基础上加1,求如果这只超级赛亚狗想要打下所有的银行所需的电脑的值的最小值。

    思路:由于每次操作都会导致相邻的点的安全值加1,所以我们(假设我们是狗,呸,我才不是狗)在最开始是一定先拿安全值最大的点开刀,防止他通过与它相邻的点安全值进一步增大。

    先举个例子,我们设如图7点的权值为Max,其余为Max-1,从7点开刀,那么最终影响答案的节点是4,5,3因为最终他们的值为Max+1。

    我们再设7点权值为Max,1,6为Max-1,其余为Max-2,我们发现,我们想打下每个节点的权值都是Max.

    不难发现,若只有一个最大值节点,那么与它直接相连的节点的安全值都会在原来基础上加1,其余加2,所以我们只需要查找Max-1的位置即可,若所有Max-1都与Max相连,那么答案就是Max,若有Max-1节点在其他地方,则为Max+1,如果连Max-1的点都没有,就是Max。

    再来一个例子考虑有多个Max的情况,上面的结论依旧成立,所以我们需要判断所有Max是否都连在同一个点上,或者都连在其中一个Max上,这样答案就一定是Max+1,否则就是Max+2;

    假设上图1,3,4,2号为Max,则打下3,4所需的值就是Max+1,答案即为Max+1。

    假设上图4,3,2号位Max,我们此时就要注意不能从Max开始,而应从1号开始,答案仍为Max+1.

    假设1,6为Max,此时打下六号所需值为Max+2,答案即为Max+2;

    总结:

    1.只有一个Max找Max-1位置,都与Max直接相连则答案为Max,否则为Max+1.

    2.有多个Max找Max,都连在一起则为Max+1,否则为Max+2

    最后注意细节计算即可:

    上代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 using namespace std;
     6 typedef long long ll;
     7 const int N=5e6+10;
     8 int Head[N],tot;
     9 ll val[N],totm,totc;
    10 struct Node{
    11     int next,to;
    12 }edge[N];
    13 ll MAX(ll a,ll b){
    14     return a>b?a:b;
    15 }
    16 void Add(int x,int y){ 
    17     edge[++tot].to=y;
    18     edge[tot].next=Head[x];
    19     Head[x]=tot;
    20 }
    21 int main(){
    22     int n;
    23     ll Max=-2147483646,t;
    24     scanf("%d",&n);
    25     for(int i=1;i<=n;++i){
    26         scanf("%lld",&val[i]);
    27         if(val[i]>Max){  //寻找最大值并找到一个Max位置 
    28             Max=val[i];
    29             t=i;
    30         }
    31     }
    32     for(int i=1;i<=n;++i){  //计算Max,Max-1数量 
    33         if(val[i]==Max) totm++;
    34         if(val[i]==Max-1) totc++;
    35     }
    36     for(int i=1;i<n;++i){
    37         int a,b;
    38         scanf("%d%d",&a,&b);
    39         Add(a,b);Add(b,a);
    40     }
    41     if(totm==1){   //Max只有一个 
    42         if(!totc){ //无Max-1直接输出 
    43             printf("%d
    ",Max);
    44             return 0;
    45         }
    46         else{
    47             int now=0;
    48             for(int i=Head[t];i;i=edge[i].next){
    49                 int v=edge[i].to;
    50                 if(val[v]==Max-1) now++;   //判断Max-1是否都连在Max上 
    51             }
    52             if(now==totc){
    53                 printf("%d
    ",Max);
    54                 return 0;
    55             }
    56             else{
    57                 printf("%d
    ",Max+1);
    58                 return 0; 
    59             }
    60         }
    61     }
    62     if(totm>=2){  //多个Max 
    63         for(int i=1;i<=n;++i){   //看所有Max是否连于一点 
    64             int cnt=0;
    65             for(int j=Head[i];j;j=edge[j].next){
    66                 int v=edge[j].to;
    67                 if(val[v]==Max) cnt++;
    68             }
    69             if(val[i]!=Max&&cnt==totm){ //两种情况 
    70                 printf("%d
    ",Max+1);
    71                 return 0;
    72             }
    73             if(val[i]==Max&&cnt==totm-1){
    74                 printf("%d
    ",Max+1);
    75                 return 0;
    76             }
    77         }
    78     }
    79     printf("%d
    ",Max+2);  //都不满足输出Max+2 
    80     return 0;
    81 }
    View Code
  • 相关阅读:
    如何将数据库中已有表导入到powerDesigner生成pdm文件
    Delphi TcxTreelist 表格左边总是缩进去 ,好像有偏移 解决方法
    HTML、CSS、JS对unicode字符的不同处理
    老生常谈ajax
    浅谈javascript面向对象
    HTML5原生拖放实例分析
    一个小动画,颠覆你的CSS世界观
    布局神器display:table-cell
    javascript 日常总结
    G2 2.0 更灵活、更强大、更完备的可视化引擎!
  • 原文地址:https://www.cnblogs.com/li-jia-hao/p/12807912.html
Copyright © 2011-2022 走看看