1. 程式人生 > 實用技巧 >Codeforces 1388C Uncle Bogdan and Country Happiness(dfs+條件判定)

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; }