Codeforces 1388C Uncle Bogdan and Country Happiness(dfs+条件判定)

题意:一个n个点以1为根节点的树,刚开始所有人都在1,他们所要前往p【i】,每个人开始有两种状态good和bad,在前进过程中good可以转化成bad,给出h【i】经过i点(包括终点)是i点的人中good-bad人数,问h是否合理。

题解:对于i点flow【i】表示经过i点的人总数,可以得到good【i】=flow【i】+h【i】 /2,good【i】必须为整数解,并且<=flow【i】;good会转化成bad,则以root为根的子树中,必须满足所有深度为1的节点的sigma(good【i】)<=good[root]。

#include <bits/stdc++.h>
#define IO_read ios::sync_with_stdio(false);cin.tie(0)
#define fre freopen("C:\\in.txt", "r", stdin)
#define _for(i,a,b) for(int i=a; i< b; i++)
#define _rep(i,a,b) for(int i=a; i<=b; i++)
#define inf 0x3f3f3f3f
#define lowbit(a) ((a)&-(a))
using namespace std;
typedef long long ll;
template <class T>
void read(T &x)
{
    char c; bool op=0;
    while(c=getchar(), c<'0'||c>'9') if(c=='-') op=1;
    x=c-'0';
    while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0';
    if(op) x=-x;
}
template <class T>
void write(T x)
{
    if(x<0) putchar('-'), x=-x;
    if(x>=10) write(x/10);
    putchar('0'+x%10);
}

const int maxn=2e5+5;
int T, n, m;
int p[maxn], h[maxn];
int good[maxn], size_good[maxn], flow[maxn];
int tot, head[maxn];
struct Edge{
    int to, next;
    Edge(int _to=0, int _next=0): to(_to), next(_next) {}
}edge[maxn];
void addedge(int u, int v){
    edge[++tot]=Edge(v, head[u]);
    head[u]=tot;
}

int ok;
void dfs1(int u, int pre)
{
    flow[u]=p[u];
    for(int i=head[u]; i!=-1; i=edge[i].next){
        int v=edge[i].to;
        if(v==pre) continue;
        dfs1(v, u);
        flow[u]+=flow[v];
    }
    if((h[u]+flow[u])%2==0) good[u]=(h[u]+flow[u])/2;
    else ok=0;
    if(good[u]>flow[u]) ok=0;
}

void dfs2(int u, int pre)
{
    //size_good[u]=good[u];
    size_good[u]=0;
    for(int i=head[u]; i!=-1; i=edge[i].next){
        int v=edge[i].to;
        if(v==pre) continue;
        dfs2(v, u);
        //size_good[u]+=size_good[v]; //WA了2次,这里写错了
        size_good[u]+=good[v];
    }
    if(good[u]<size_good[u]) ok=0;
}

void init()
{
    memset(head, -1, sizeof(head));
    tot=0;
    ok=1;
}

int main()
{
    fre;
    read(T);
    while(T--)
    {
        read(n), read(m);
        init();
        _rep(i, 1, n) read(p[i]);
        _rep(i, 1, n) read(h[i]);
        _for(i, 1, n){
            int u, v;
            read(u), read(v);
            addedge(u, v), addedge(v, u);
        }
        dfs1(1, 0);
        if(ok) dfs2(1, 0);
        printf(ok? "YES\n":"NO\n");
    }
    return 0;
}

 

posted @ 2020-08-02 15:37  N_Yokel  阅读(187)  评论(0编辑  收藏  举报