zoukankan      html  css  js  c++  java
  • Codeforces Round #408 (Div. 2) C. Bank Hacking

    http://codeforces.com/contest/796/problem/C

    Although Inzane successfully found his beloved bone, Zane, his owner, has yet to return. To search for Zane, he would need a lot of money, of which he sadly has none. To deal with the problem, he has decided to hack the banks.

    There are n banks, numbered from 1 to n. There are also n - 1 wires connecting the banks. All banks are initially online. Each bank also has its initial strength: bank i has initial strength ai.

    Let us define some keywords before we proceed. Bank i and bank j are neighboring if and only if there exists a wire directly connecting them. Bank i and bank j are semi-neighboring if and only if there exists an online bank k such that bank i and bank k are neighboring and bank k and bank j are neighboring.

    When a bank is hacked, it becomes offline (and no longer online), and other banks that are neighboring or semi-neighboring to it have their strengths increased by 1.

    To start his plan, Inzane will choose a bank to hack first. Indeed, the strength of such bank must not exceed the strength of his computer. After this, he will repeatedly choose some bank to hack next until all the banks are hacked, but he can continue to hack bank x if and only if all these conditions are met:

    1. Bank x is online. That is, bank x is not hacked yet.
    2. Bank x is neighboring to some offline bank.
    3. The strength of bank x is less than or equal to the strength of Inzane's computer.

    Determine the minimum strength of the computer Inzane needs to hack all the banks.

    Input

    The first line contains one integer n (1 ≤ n ≤ 3·105) — the total number of banks.

    The second line contains n integers a1, a2, ..., an ( - 109 ≤ ai ≤ 109) — the strengths of the banks.

    Each of the next n - 1 lines contains two integers ui and vi (1 ≤ ui, vi ≤ nui ≠ vi) — meaning that there is a wire directly connecting banks ui and vi.

    It is guaranteed that the wires connect the banks in such a way that Inzane can somehow hack all the banks using a computer with appropriate strength.

    Output

    Print one integer — the minimum strength of the computer Inzane needs to accomplish the goal.

     

    题意:

    一只狗要入侵银行抢钱,一开始每个银行都是在线的,银行与银行直接通过电线相连,如果银行 i 和 j 直接连接,就称它们为相邻的,如果i 和 j 之间通过了 k 相连,就称它们为半相邻。

    现在每个银行有个初始能力值a,狗的电脑也有能力值,入侵的条件是能力值不小于银行的能力值。一开始狗可以随意选择一个银行作为起点,然后该银行下线,与它相邻和半相邻的银行的能力值都加1。

    现在要求狗的电脑的最小能力值使得可以成功入侵所有银行。

     

    思路:

    首先要能看出这道题目的模型就是树。

    一开始我们随意选择选择一个银行作为起点,遍历完树上所有结点后,你会发现与它相邻的银行会变为a+1,其余都会变成a+2。

    我们找到一开始所有银行中的最大值MAX,答案只可能是MAX, MAX+1, MAX+2当中的一个。

    ① 如果为MAX,那么MAX为根,而且所有的MAX-1都必须和根相连。

    ② 如果为MAX+1,存在那么一个根,所有的MAX都和它相连。

    ③ 其余的就是MAX+2。

    那么,我们只需要枚举一遍,将每个银行作为起点判断一下其最小值即可。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 using namespace std;
    12 typedef long long ll;
    13 typedef pair<int,int> pll;
    14 const int INF = 0x3f3f3f3f;
    15 const int maxn=3*1e5+5;
    16 
    17 int a[maxn];
    18 int n,m,k;
    19 vector<int> g[maxn];
    20 
    21 int main()
    22 {
    23     //freopen("in.txt","r",stdin);
    24     while(~scanf("%d",&n))
    25     {
    26         int MAX = -1e9-5;
    27         for(int i=1;i<=n;i++)
    28         {
    29             scanf("%d",&a[i]);
    30             if(a[i] > MAX)  MAX = a[i];
    31         }
    32 
    33         for(int i=1;i<=n;i++)  g[i].clear();
    34 
    35         for(int i=1;i<n;i++)
    36         {
    37             int u,v;
    38             scanf("%d%d",&u,&v);
    39             g[u].push_back(v);
    40             g[v].push_back(u);
    41         }
    42 
    43         int sum1=0,sum2=0;
    44         for(int i=1;i<=n;i++)
    45         {
    46             if(a[i]==MAX)  sum1++;
    47             else if(a[i]==MAX-1)  sum2++;
    48         }
    49 
    50         bool flag=true;
    51         if(sum1==1)  //如果只有一个最大值,判断所有MAX-1是否和它相连
    52         {
    53             for(int u=1;u<=n;u++)
    54             {
    55                 int c=0;
    56                 if(a[u]==MAX)
    57                 {
    58                     for(int i=0;i<g[u].size();i++)
    59                     {
    60                         int v=g[u][i];
    61                         if(a[v]==MAX-1) c++;
    62                     }
    63                     if(c==sum2)
    64                     {
    65                         printf("%d
    ",MAX);
    66                         flag=false;
    67                     }
    68                 }
    69             }
    70         }
    71 
    72         if(flag)  //如果有多个最大值,判断是否存在一个根,所有MAX都与它相连
    73         for(int u=1;u<=n;u++)
    74         {
    75             int c=0;
    76             for(int i=0;i<g[u].size();i++)
    77             {
    78                 int v=g[u][i];
    79                 if(a[v]==MAX) c++;
    80             }
    81             if(sum1==c || (sum1==c+1&&a[u]==MAX))
    82             {
    83                 printf("%d
    ",MAX+1);
    84                 flag=false;
    85                 break;
    86             }
    87         }
    88 
    89         if(flag) printf("%d
    ",MAX+2);  //其余情况
    90     }
    91     return 0;
    92 }
  • 相关阅读:
    maven创建父子工程
    webservice之jersey简单实用
    EL表达式处理字符串
    oracle不等于1怎么查?
    day_07 搭建Tomcat服务器使用Servlet服务,后端接受前端请求过来的表单数据并使用
    Day_06 流程控制-循环结构-嵌套循环结构的原理解析
    Day05_流程控制02 循环结构
    day_5 流程控制 选择结构的两种常用语句的使用语法
    day_04 运算符详解
    day_03 变量的数据类型详解
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7028990.html
Copyright © 2011-2022 走看看