Time limit : 2sec / Memory limit : 256MB
Score : 700 points
There is a tree with N vertices, numbered 1 through N. The i-th of the N−1 edges connects vertices ai and bi.
Currently, there are Ai stones placed on vertex i. Determine whether it is possible to remove all the stones from the vertices by repeatedly performing the following operation:
Note that the operation cannot be performed if there is a vertex with no stone on the path.
The input is given from Standard Input in the following format:
N A1 A2 … AN a1 b1 : aN−1 bN−1
If it is possible to remove all the stones from the vertices, print YES
. Otherwise, print NO
.
5 1 2 1 1 2 2 4 5 2 3 2 1 3
YES
All the stones can be removed, as follows:
3 1 2 1 1 2 2 3
NO
6 3 2 2 2 2 2 1 2 2 3 1 4 1 5 4 6
YES
分析:考虑点与边的关系:
1.点为叶子节点,相邻的边权值为点权值;
2.点不为叶子,相邻的边权值和为点权值二倍;
这样dfs可以得出所有边权值;
以下几种情况不可行:
1.存在负权值;
2.与一个点相邻的边权值均不应大于点权值,否则不能两两分组;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <bitset> #include <map> #include <queue> #include <stack> #include <vector> #define rep(i,m,n) for(i=m;i<=n;i++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define sys system("pause") const int maxn=1e5+10; using namespace std; inline ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} inline ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} inline void umax(ll &p,ll q){if(p<q)p=q;} inline void umin(ll &p,ll q){if(p>q)p=q;} inline ll read() { ll x=0;int f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } int n,m,k,t,a[maxn]; ll cnt[maxn]; vi e[maxn]; bool flag=true; void dfs(int x,int y) { if(!flag)return; ll p=0; for(int z:e[x]) { if(z==y)continue; dfs(z,x); if(cnt[z]>a[x]) { flag=false; return; } p+=cnt[z]; } if((int)e[x].size()==1) { cnt[x]=a[x]; } else { cnt[x]=(ll)2*a[x]-p; if(cnt[x]<0||cnt[x]>a[x]) { flag=false; return; } } } int main() { int i,j; scanf("%d",&n); rep(i,1,n)scanf("%d",&a[i]); rep(i,1,n-1)scanf("%d%d",&j,&k),e[j].pb(k),e[k].pb(j); if(n==2) { puts(a[1]==a[2]?"YES":"NO"); return 0; } rep(i,1,n) { if((int)e[i].size()>1) { dfs(i,-1); if(!flag)puts("NO"); else if(cnt[i]!=0)puts("NO"); else puts("YES"); return 0; } } return 0; }
原文:http://www.cnblogs.com/dyzll/p/6367388.html