zoukankan      html  css  js  c++  java
  • Cleaning

    Cleaning


    Time limit : 2sec / Memory limit : 256MB

    Score : 700 points

    Problem Statement

    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,biN
    • 0≦Ai≦109
    • The given graph is a tree.

    Input

    The input is given from Standard Input in the following format:

    N
    A1 A2AN
    a1 b1
    :
    aN−1 bN−1
    

    Output

    If it is possible to remove all the stones from the vertices, print YES. Otherwise, print NO.


    Sample Input 1

    5
    1 2 1 1 2
    2 4
    5 2
    3 2
    1 3
    

    Sample Output 1

    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.

    Sample Input 2

    3
    1 2 1
    1 2
    2 3
    

    Sample Output 2

    NO
    

    Sample Input 3

    6
    3 2 2 2 2 2
    1 2
    2 3
    1 4
    1 5
    4 6
    

    Sample Output 3

    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;
    }
  • 相关阅读:
    未能加载文件或程序集“Oracle.DataAccess”或它的某一个依赖项。试图加载格式不正确的程序
    Silverlight Visifire控件 后台设置颜色
    silverlight 生成图表 WCF 解析XML代码.svc.cs 文件
    silverlight 生产图表(动态图表类型,Y轴数量) .xaml.cs文件
    Silverlight Visifire控件应用去水印
    .net简单的aspx创建
    Silverlight Visifire控件 .net后台控制aspx页面控件的显示与隐藏,动态给控件赋值,选定默认值的设定
    .net后台 Silverlight 页面 动态设置 ASPX 页面 控件的Margin值(位置设置)
    转载 Silverlight实用窍门系列:1.Silverlight读取外部XML加载配置---(使用WebClient读取XAP包同目录下的XML文件))
    java 读取Excel文件并数据持久化方法Demo
  • 原文地址:https://www.cnblogs.com/dyzll/p/6367388.html
Copyright © 2011-2022 走看看