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;
}

浙公网安备 33010602011771号