博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AtCoder Grand Contest 010 --C:Cleaning
阅读量:4564 次
发布时间:2019-06-08

本文共 2180 字,大约阅读时间需要 7 分钟。

Cleaning

时间限制: 2 Sec 内存限制: 256 MB

题目描述

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:

Select a pair of different leaves. Then, remove exactly one stone from every vertex on the path between those two vertices. Here, a leaf is a vertex of the tree whose degree is 1, and the selected leaves themselves are also considered as vertices on the path connecting them.

Note that the operation cannot be performed if there is a vertex with no stone on the path.

Constraints

2≤N≤105
1≤ai,bi≤N
0≤Ai≤109
The given graph is a tree.

输入

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.

样例输入

51 2 1 1 22 45 23 21 3

样例输出

YES

提示

All the stones can be removed, as follows:

Select vertices 4 and 5. Then, there is one stone remaining on each vertex except 4.

Select vertices 1 and 5. Then, there is no stone on any vertex.

分析

对于每颗子树,该子树的根上的石头有两种消去方式:

  • 选择两个子树内部的叶子
  • 选择一个子树中的叶子和子树外部的叶子

我们假设通过第一种方式消去的根的石头数为\(p\),那么第二种方式消去数应为 \(A[root]-p\)。根消去\(p\)时,这个根的儿子应当总共消去\(2p\),消去后应满足式子\[sum-2p=A[root]-p\]所以\(p=sum-A[root]\),这样操作一次之后就可以把子树等价为还有\(A[root]-p\)个石头的叶子。

#include 
#include
#include
#include
#include
#include
using namespace std;const int maxn=200050;typedef long long ll;struct Edge{ int v,nxt;}e[maxn*2];int h[maxn],tot;void addEdge(int x,int y){ e[++tot]=(Edge){y,h[x]}; h[x]=tot;} ll w[maxn];bool ans=true;ll dfs(int x,int x_fa){ ll sum=0,cnt=0,M=0; for (int i = h[x]; i ; i=e[i].nxt) { if(e[i].v!=x_fa){ ll t=dfs(e[i].v,x); sum+=t; M=max(M,t); cnt++; } } if(cnt==0) return w[x]; if(cnt==1){ if(sum!=w[x]) ans=false; return sum; } ll p=sum-w[x]; if(p<0||w[x]
1) root=i; } if(dfs(root,root)!=0) ans=false; if(ans) printf("YES\n"); else printf("NO\n"); return 0;}

转载于:https://www.cnblogs.com/sciorz/p/8900563.html

你可能感兴趣的文章
简单理解什么是递归(阶乘演示)
查看>>
http协议
查看>>
js倒计时,页面刷新时,不会从头计时
查看>>
洛谷1156垃圾陷阱
查看>>
python ==》 递归
查看>>
简单网络请求封装
查看>>
django —— MVT模型
查看>>
oracle 静默安装
查看>>
Python3基础(2)模块、数据类型及运算、进制、列表、元组、字符串操作、字典...
查看>>
服务器上centos 7 配置静态IP
查看>>
C# unsafe模式内存操作深入探索
查看>>
Redis拾遗(一)
查看>>
js字符串转换为Json对象的三种写法
查看>>
Is it possible to display icons in a PopupMenu?
查看>>
制作导航条
查看>>
iOS中的内存管理1
查看>>
23种设计模式全解析
查看>>
Learning Python 008 正则表达式-003 sub()方法
查看>>
要检测两个C文件的代码的抄袭情况
查看>>
iOS开发之应用内支付IAP全部流程
查看>>