题目链接: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 " , ans); return 0; }