Codeforces Round #408 (Div. 2) C. Bank Hacking

题目链接:http://codeforces.com/contest/796/problem/C

题意:给出一个有n节点的树,每个节点的权值表示hack一所银行的所需要的能力值,每hack一所银行,他相邻的银行和次相邻的银行权值

加1。所谓次相邻,就是有一个k银行没被hack屌,且k与i相邻,k与j相邻,i与j为次相邻。一开始它允许hack任意一所银行,但是之后要满

足一些条件,当前银行没被hack屌,而且要hack的银行一定要直接链接着被hack过的银行。最后问最小需要都少能力值才能hack屌所有银

题解:首先要理解这题结果的可能性,只有可能是MAX,MAX+1,MAX+2,除了和首个hack直接相连的银行只能+1,其他都能+2

其实就是有几种情况要考虑一下。当最大值只有一个时,那么ans=MAX or MAX + 1,

例如(点值表示权值)

1-2-3-4-5(5)     4-1-2-3-5(6)

当最大值有多个时,ans=MAX+1 or MAX + 2;

MAX+1有两种情况

例如

1-2-5-3-5-2-1(6) 1-2-3-5-5(6)

             |

             5

其他情况就是MAX+2。

 

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
const int M = 3e5 + 10;
int val[M] , a[M] , x[M] , y[M] , gg;
bool IS[M];
vector<int>vc[M] , v[M];
void dfs(int pos , int pre , int flag) {
    if(flag) {
        gg = max(gg , val[pos] + 1);
    }
    else {
        gg = max(gg , val[pos] + 2);
    }
    int len = v[pos].size();
    for(int i = 0 ; i < len ; i++) {
        int u = v[pos][i];
        if(u != pre) {
            dfs(u , pos , 0);
        }
    }
}
int main() {
    int n;
    scanf("%d" , &n);
    int MAX = -1000000002;
    for(int i = 1 ; i <= n ; i++) {
        IS[i] = false;
        vc[i].clear();
        v[i].clear();
        scanf("%d" , &val[i]);
        MAX = max(MAX , val[i]);
    }
    int count = 0;
    for(int i = 1 ; i <= n ; i++) {
        if(val[i] == MAX) {
            a[count++] = i;
            IS[i] = true;
        }
    }
    for(int i = 1 ; i < n ; i++) {
        scanf("%d%d" , &x[i] , &y[i]);
        if(IS[x[i]] && IS[y[i]]) {
            vc[x[i]].push_back(y[i]);
            vc[y[i]].push_back(x[i]);
        }
    }
    int MM = 0 , pos = a[0];
    for(int i = 0 ; i < count ; i++) {
        int len = vc[a[i]].size();
        if(MM < len) {
            MM = len;
            pos = a[i];
        }
    }
    int cnt = vc[pos].size();
    int ans = MAX;
    if(count == 1) {
        for(int i = 1 ; i < n ; i++) {
            v[x[i]].push_back(y[i]);
            v[y[i]].push_back(x[i]);
        }
        int len = v[pos].size();
        for(int i = 0 ; i < len ; i++) {
            gg = MAX;
            int u = v[pos][i];
            dfs(u , pos , 1);
            ans = max(ans , gg);
        }
    }
    else {
        if(cnt == count - 1) {
            ans = MAX + 1;
        }
        else {
            int pos2 = 1;
            MM = 0;
            for(int i = 1 ; i < n ; i++) {
                if(IS[x[i]] && !IS[y[i]]) {
                    v[y[i]].push_back(x[i]);
                    int len = v[y[i]].size();
                    if(len > MM) {
                        MM = len;
                        pos2 = y[i];
                    }
                }
                if(!IS[x[i]] && IS[y[i]]) {
                    v[x[i]].push_back(y[i]);
                    int len = v[x[i]].size();
                    if(len > MM) {
                        pos2 = x[i];
                    }
                }
            }
            int len = v[pos2].size();
            if(len == count) {
                ans = MAX + 1;
            }
            else {
                ans = MAX + 2;
            }
        }
    }
    printf("%d\n" , ans);
    return 0;
}
posted @ 2017-04-11 08:15  Gealo  阅读(158)  评论(0编辑  收藏  举报