CodeForces1388C - Uncle Bogdan and Country Happiness

题意:

n n n个城市由 n − 1 n-1 n1条路径构成一棵树。总共有 m m m人住在这些城市,第 i i i个城市住的人数是 p i p_i pi。每个人有一个心情,可能为好心情,可能为坏心情。所有人带着一种心情从城市 1 1 1(根节点)出发,出发时可能为好心情,可能为坏心情。在路径上(边)可以改变心情,但只能由好变坏,不能由坏变好。在城市里(点)不会改变心情。现在问,是否存在一种方案,使得经过城市 i i i的好心情的人数-经过城市 i i i的坏心情的人数= h i h_i hi

题解:

设经过城市 i i i的好心情的人数为 g o o d i good_i goodi,坏心情的人数为 b a d i bad_i badi。已知经过城市 i i i的总人数为
s u m i = p i + ∑ j 为 i 儿 子 s u m j sum_i=p_i+\sum_{j为i儿子}^{}sum_j sumi=pi+jisumj
可以得到两个式子
s u m i = g o o d i + b a d i sum_i=good_i+bad_i sumi=goodi+badi

h i = g o o d i − b a d i h_i=good_i-bad_i hi=goodibadi

由此可得
g o o d i = ( s u m i + h i ) / 2 good_i=(sum_i+h_i)/2 goodi=(sumi+hi)/2

b a d i = s u m i − g o o d i bad_i=sum_i-good_i badi=sumigoodi

那么哪些情况是不合理的呢?
g o o d i < 0 , b a d i < 0 , g o o d i − b a d i ≠ h i good_i<0,bad_i<0,good_i-bad_i\neq h_i goodi<0,badi<0,goodibadi=hi
(当 ( s u m i + h i ) (sum_i+h_i) (sumi+hi)为奇数的时候,当然是不合理的,为了好看,我们将这个判断转化成了最后的不等式)

那是不是这样就好了呢?当然不是。路过城市 i i i的人中,因为坏心情只能还是坏心情,所以经过城市 i i i中好心情的人数,应该至少满足 i i i所有儿子的好心情的人数。
g o o d i ≥ ∑ j 为 i 的 儿 子 g o o d j good_i\geq \sum_{j为i的儿子}^{} good_j goodijigoodj
分析完之后,一遍 dfs 就解决了这个问题。

AC代码:

#include 
#define pb push_back 
#define fir first
#define sec second
#define ms(a,b) memset(a,b,sizeof(a)) 
#define INF 0x3f3f3f3f
#define sp system("pause")
#define multi int t;cin>>t;while(t--) 
using namespace std;
typedef long long ll;
typedef double db;
const int N=1e5+5;
const int mod=10007;
const db pi=acos(-1.0);
vectortr[N];
int p[N],h[N],good[N],bad[N],sum[N];
bool dfs(int u,int fa)
{
    sum[u]=p[u];
    int g=0;
    for(int v:tr[u]){
        if(v==fa) continue;
        if(dfs(v,u)){
            sum[u]+=sum[v];
            g+=good[v];
        }else return 0;
    }
    good[u]=(sum[u]+h[u])/2;
    bad[u]=sum[u]-good[u];
    if(good[u]>n>>m;
        for(int i=1;i<=n;i++){
            tr[i].clear();
            good[i]=bad[i]=sum[i]=0;
            cin>>p[i];
        }
        for(int i=1;i<=n;i++) cin>>h[i];
        for(int i=1,x,y;i>x>>y;
            tr[x].pb(y);
            tr[y].pb(x);
        }
        if(dfs(1,-1)) cout<<"YES"<

你可能感兴趣的:(搜索)