题目描述:
样例输入1:
5
1 3 1 3 2
2 5
3 4
4 5
1 5
4
样例输出1:
6
样例输入 2:
3
2 1 1
3 2
1 2
3
样例输出 2:
2
数据规模:
对于 30% 的数据:n≤5;ai≤5;
对于 100% 的数据:1≤n≤100000;0≤ai≤109;1≤x≤n。
附代码:
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<queue>
#include<string>
#include<cmath>
#include<cctype>
#include<set>
#include<map>
#include<iomanip>
#include<algorithm>
#include<vector>
using namespace std;
const int N=100010;
long long tot,t,n,f[N],a[N],go[N*2],next[N*2],first[N];
void create(long long a,long long b)
{
tot++;
next[tot]=first[a];
first[a]=tot;
go[tot]=b;
}
void work(long long x,long long fa)
{
long long j,tot=0;
vector<long long>vec;
if(a[x]==0) return;
for(long long i=first[x];i;i=next[i])
if(go[i]!=fa)
{
work(go[i],x);
vec.push_back(f[go[i]]);
tot++;
}
sort(vec.begin(),vec.end());
a[x]--;
f[x]=1;
for(long long i=tot;i>=1;i--)
{
j=vec[i-1];
if(a[x]==0) break;
if(j!=0)
{
f[x]+=j+1;
a[x]--;
}
else break;
}
for(long long i=first[x];i;i=next[i])
if(go[i]!=fa)
{
j=min(a[x],a[go[i]]);
a[x]-=j;
f[x]+=2*j;
}
}
int main()
{
//freopen("tongue.in","r",stdin);
//freopen("tongue.out","w",stdout);
scanf("%I64d",&n);
for(long long i=1;i<=n;i++)
scanf("%I64d",&a[i]);
for(long long i=1;i<=n-1;i++)
{
long long x,y;
scanf("%I64d%I64d",&x,&y);
create(x,y);
create(y,x);
}
scanf("%I64d",&t);
a[t]++;
work(t,0);
printf("%I64d",f[t]-1);
return 0;
}