题目大意是有n个结点,n-1条边,然后如果删除本结点,与本结点直接相连的结点权值加1其余间接相连的加2,然后让你求最少需要多少vlaue能把所有的边都删除。
这题其实一道分类讨论的题目,假设所有的点的最大权值为maxa,有此最大权值的个数为mx,而maxa-1的个数有mc个,存在三种情况:
1.答案为maxa, 当mx==1,且与maxa直接相连的结点个数==mc。
2.答案为maxa+1, 当mx==1,且与maxa直接相连的结点个数<mc或者存在一个结点能连接所有的最大值点。
3.其余情况均为maxa+2。
#include<iostream>
#include<vector>
#include<algorithm>
#define maxn 300100
using namespace std;
int a[maxn];
vector<int> m[maxn];
int main()
{
int n;
cin>>n;
for(int i=1; i<=n; i++)
scanf("%d", &a[i]);
for(int i=1; i<=n-1; i++)
{
int x, y;
scanf("%d%d", &x, &y);
m[x].push_back(y);
m[y].push_back(x);
}
int maxa = -1000005000;
for(int i=1; i<=n; i++)
maxa=max(maxa,a[i]);
int mx = 0, mc = 0;
int u;
for(int i=1; i<=n; i++)
{
if(a[i] == maxa)
{
mx++;
u = i;
}
if(a[i] == maxa-1)
mc++;
}
if(mx == 1)
{
int count = 0;
for(int i=0; i<m[u].size(); i++)
{
int v = m[u][i];
if(a[v] == maxa - 1)
count++;
}
if(count == mc)
printf("%d\n",maxa);
else
printf("%d\n",maxa+1);
}
else
{
int flag = 0;
for(int i=1; i<=n; i++)
{
int count = 0;
if(a[i] == maxa)
count++;
for(int j=0; j<m[i].size(); j++)
{
int v=m[i][j];
if(a[v]==maxa)
count++;
}
if(count == mx)
flag = 1;
}
if(flag)
printf("%d\n",maxa+1);
else
printf("%d\n",maxa+2);
}
return 0;
}