题解 AT2304 【Cleaning】
戳我= ̄ω ̄=
这个里面的花,我们在所有的叶子节点
那么会前文已说,从每个节点继续往上飞的小精灵数是固定的,所以每个节点处组成朋友的小精灵对数也是固定的,重点在求出最多可以组成多少对朋友,判断能不能达成石头恰好被捡完这个目标。
那么这个找朋友的过程怎么进行呢?我们让从同一个儿子节点飞上来的小精灵暂时站在一艘船上,由于只有不同船上的小精灵可以组队,所以有精灵的船越多越有利。所以我们每次选择两艘小精灵数最多的船,让它们上面各一个小精灵组成一对,然后她们两个下船,以此类推。
于是我们发现最多能组的队数只有两种情况,一种是有一艘船上的小精灵特别多,多到别的船都空了这艘船上还有很多小精灵单身。一种是我们这么操作着操作着所有船上的小精灵数越来越多接近,最后几乎所有的小精灵都有了朋友,但是如果总精灵数是奇数,那必然有一个小精灵找不到朋友。
最多组的队数与想要石头恰好被捡完应该组的队数比较即可判断。
#include<bits/stdc++.h>
using namespace std;
#define RI register int
int read() {
int q=0;char ch=' ';
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar();
return q;
}
typedef long long LL;
const int N=100005;
int n,tot,h[N],ne[N<<1],to[N<<1],du[N];
LL a[N],f[N];
void add(int x,int y) {to[++tot]=y,ne[tot]=h[x],h[x]=tot;}
void dfs(int x,int las) {
if(du[x]==1) {f[x]=a[x];return;}
LL orzabs=0,p,mx=0;
for(RI i=h[x];i;i=ne[i]) {
if(to[i]==las) continue;
dfs(to[i],x),f[x]+=f[to[i]],mx=max(mx,f[to[i]]);
}
if(mx>f[x]-mx) p=f[x]-mx;
else p=f[x]/2;
if(f[x]<a[x]) {puts("NO");exit(0);}
if(f[x]-a[x]>p) {puts("NO");exit(0);}
f[x]-=(f[x]-a[x])*2LL;
}
int main()
{
int x,y;
n=read();
for(RI i=1;i<=n;++i) a[i]=read();
if(n==2) {
if(a[1]==a[2]) puts("YES");
else puts("NO");
return 0;
}
for(RI i=1;i<n;++i)
x=read(),y=read(),add(x,y),add(y,x),++du[x],++du[y];
for(RI i=1;i<=n;++i) if(du[i]>1) {
dfs(i,0);
if(f[i]) puts("NO");
else puts("YES");
return 0;
}
return 0;
}