• Codeforces Round #660 (Div. 2) Uncle Bogdan and Country Happiness dfs


    题目链接:Uncle Bogdan and Country Happiness

    题意:

    t组输入,每组数据输入如下

    首先一个n代表有n个城市,所有城市总人数为m,后面输入pi表示第i个城市的居住人数,后面的hi表示经过这个城市的人中  开心的人数-伤心的人数

    后面输入n-1条无向边,每条边的长度都一样

    这个图的结构是树形结构,且刚开始所有人都在1点,也就是根节点。他们会走最短路径去回到他们居住的城市

    所有人在走的路上都可能由好心情变成坏心情,但是坏心情不会变成好心情,且在城市内这个变化不会发生

    题目让你判断给出的hi是否全部正确,是就输出YES

    题解:

    因为我们不知道经过某个城市的总人数,所以我们需要从树的根节点开始dfs,伤心人数用bad来表示,开心人数用good来表示,totali表示经过i点的总人数

    我们得到两个方程式

    good+bad=totali

    good-bad=hi

    这样我们可以求出来good和bad,但是我们还需要去判断这个good正确不正确,因为所有人在路上都可能由好心情变成坏心情,所以说越靠近根节点,那么good的数量肯定会更大,所以我们统计一下子节点算出来的good的和ans,用ans和此节点算出来的good作比较,如果ans>good那就肯定不行

     

    还要判断一下abs(hi)<=total

    代码:

    #include<stack>
    #include<queue>
    #include<map>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    const int mod=1e9+7;
    const double eps=1e-8;
    ll p[maxn],h[maxn],flag,total[maxn],good[maxn];
    vector<ll>w[maxn];
    void add_edge(ll x,ll y)
    {
        w[x].push_back(y);
        w[y].push_back(x);
    }
    void dfs(ll x,ll fx)
    {
        ll len=w[x].size(),sum=0;
        total[x]=p[x];
        for(ll i=0;i<len;++i)
        {
            ll y=w[x][i];
            if(y==fx) continue;
            dfs(y,x);
            total[x]+=p[y];
            sum+=good[y];
            if(flag) return;
        }
        p[x]=total[x];
        if(flag) return;
        //if(total[x]==0) return;  之前认为total等于0就不需要判断,没想不行
        //因为题目让你判断hi的值是否全部正确,就算total等于0,我们也需要去判断。。。
        if(abs(h[x])>total[x]) {
            flag=1;
            return;
        }
        if((h[x]+total[x])%2==0 && ((h[x]+total[x])/2)>=h[x])
        {
    
            //printf("%d******%d
    ",x,total[x]);
            good[x]=(h[x]+total[x])/2;
            if(good[x]<sum)
            {
                flag=1;
                return;
            }
        }
        else
        {
            flag=1;
        }
        return;
    }
    int main()
    {
        ll t;
        scanf("%lld",&t);
        while(t--)
        {
            ll n,m;
            flag=0;
            memset(good,0,sizeof(good));
            scanf("%lld%lld",&n,&m);
            for(ll i=1;i<=n;++i)
                w[i].clear();
            for(ll i=1;i<=n;++i)
                scanf("%lld",&p[i]);
            for(ll i=1;i<=n;++i)
                scanf("%lld",&h[i]);
            for(ll i=1;i<n;++i)
            {
                ll x,y;
                scanf("%lld%lld",&x,&y);
                add_edge(x,y);
            }
            dfs(1,0);
            if(flag || total[1]!=m)
            {
                printf("NO
    ");
            }
            else
            {
                printf("YES
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    kendo ui 查找treelist里的子控件并设置是否显示的方法
    KendoUi下的DatePicker在谷歌浏览器上不能正常显示时间的解决方法
    asp.net 第三方UI控件 Telerik KendoUI 之 TreeVIew 的用法记录
    mysql批量更新数据,即:循环select记录然后更新某一字段
    Sql语句备份Sqlserver数据库
    3des用法示例,已测试
    制作Windows服务项目详细攻略
    利用好压在C#程序里实现RAR格式的压缩和解压功能
    winform里textBox无法获得焦点的解决方案
    Shell脚本批量重命名案例
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/13518792.html
Copyright © 2020-2023  润新知