ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF796C Bank Hacking

2020-04-30 11:51:16  阅读:287  来源: 互联网

标签:安全值 int Max ll 打下 Hacking CF796C 节点 Bank


 

 

 

 

 

题意:给定一棵树,每个节点上有一个银行,最初所有银行全部在线,有一只狗想要打下所有银行(没错是狗),每个银行都有一个安全值,狗的电脑的值必须大于等于所攻下银行的安全值,且每打下一个银行后和它距离为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\n",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\n",Max);
54                 return 0;
55             }
56             else{
57                 printf("%d\n",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\n",Max+1);
71                 return 0;
72             }
73             if(val[i]==Max&&cnt==totm-1){
74                 printf("%d\n",Max+1);
75                 return 0;
76             }
77         }
78     }
79     printf("%d\n",Max+2);  //都不满足输出Max+2 
80     return 0;
81 }
View Code

 

标签:安全值,int,Max,ll,打下,Hacking,CF796C,节点,Bank
来源: https://www.cnblogs.com/li-jia-hao/p/12807912.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有