Codeforces Round #408 /Mcvi Round #8 C Bank Hacking

题目大意:
n家银行有n-1条网线相连,最初第i家银行的实力为a[i],且所有银行都在线。如果i和j有一条网线直接相连,则相邻;若i和k相邻,k和j相邻,则称i和j次相邻。当银行被攻击后,立即断线,与其相邻、次相邻的银行实力加1。现在Inzane开始他hack所有银行的计划,他选择hack的银行,需要满足3个条件:这家银行仍在线;它的相邻银行已经被hack;自己的实力需不低于银行实力。问:Inzane的实力至少为多少才能完成计划?
题解:
题目繁冗,简单来说就是,他任意选择一家银行开始实施计划,剩下的银行必须与hack过的银行相邻,即有一定顺序。记目前被攻击的银行为i,相邻银行为j,次相邻银行为k,且j和k未被攻击,据题意,k银行的实力最终会且只会+2(i银行被攻击时+1,j银行被攻击时再+1)。所以,答案必然为max,max+1,max+2中的一个值。[答案为max的情况是,只有一家银行的实力为max,且实力为max-1的银行全部与其相邻。答案为max+1的情况是,某家实力为max的银行,与其余所有实力为max的银行相邻。其余情况全部为max+2。]

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;


const int maxn = 3 * 1e5 + 5;
vector <int> v[300005];
int num[maxn][3];
int main()
{
    int n,x,y,sum1,sum2,a[maxn];
    scanf("%d",&n);
    int maxv=-1000000001,maxno=0;
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>maxv)
        {
            maxv=a[i];
            maxno=i;
        }
    }
    for (int i=1;i<n;i++)
    {
        scanf("%d %d",&x,&y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    int tot1=0,tot2=0;
    for (int i=1;i<=n;i++)
    {
        if (a[i]==maxv) tot1++;
        if (a[i]==maxv-1) tot2++;
    }
    for (int i=1;i<=n;i++)
    {
        sum1=0,sum2=0;
        if (a[i]==maxv) sum1++;
        if (a[i]==maxv-1) sum2++;
        int m=v[i].size();
        for (int j=0;j<m;j++)
        {
            if (a[v[i][j]]==maxv) sum1++;
            if (a[v[i][j]]==maxv-1) sum2++;
        }
        num[i][1]=sum1;
        num[i][2]=sum2;
    }
    if (tot1==1)
    {
        if (num[maxno][2]==tot2)
        {
            printf("%d",maxv);
            return 0;
        }
    }
    for (int i=1;i<=n;i++)
        if (num[i][1]==tot1)
    {
        printf("%d",maxv+1);
        return 0;
    }
    printf("%d",maxv+2);
    return 0;
}

题意要理解正确,不然就只有wa了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值