zoukankan      html  css  js  c++  java
  • Codeforces Round #646 (Div. 2) E——Tree Shuffling 思维

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 1000005
    #define inf 2e9
    using namespace std;
    inline int read()
    {
        int x=0,w=1;
        char c=getchar();
        while(c<'0'||c>'9')
        {
            if(c=='-') w=-1;
            c=getchar();
        }
        while(c<='9'&&c>='0')
        {
            x=(x<<1)+(x<<3)+c-'0';
            c=getchar();
        }
        return w==1?x:-x;
    }
    
    ll n,t1,t2,t3,f[maxn],s1[maxn],s2[maxn],ans;
    struct node
    {
        ll a,b,c,id,w1,w2;
    } p[maxn];
    vector <int> mp[maxn];
    
    inline void dfs(int u,int fa)
    {
        f[u]=fa;
        s1[u]=p[u].w1;//子树中点的权值
        s2[u]=p[u].w2;
        for(int i=0; i<mp[u].size(); i++)
        {
            int v=mp[u][i];
            if(v==fa)
                continue;
            dfs(v,u);
            s1[u]+=s1[v];
            s2[u]+=s2[v];
        }
    }
    //                        父节点 父节点代价
    inline void dfs2(int u,int fa,ll mn)
    {
        for(int i=0; i<mp[u].size(); i++)
        {
            int v=mp[u][i];
            if(v==fa)
                continue;
            if(p[u].a<mn) //当前点代价小于父节点
            {
                ll tmp=min(s1[u],s2[u]);
                ans+=tmp*p[u].a*2;
                ans-=tmp*mn*2;
                mn=p[u].a;
            }
            dfs2(v,u,mn);
        }
    }
    
    int main()
    {
        n=read();
        for(int i=1; i<=n; i++)
        {
            p[i].a=read(),p[i].b=read(),p[i].c=read();
            t1+=p[i].b;
            t2+=p[i].c;
            p[i].id=i;
            if(p[i].b!=p[i].c)//如果需要变换
            {
                if(p[i].b==0) //初始值是0,则需要变成1,就是w1
                    p[i].w1=1;
                else
                    p[i].w2=1; //初始值是1,需要变成0, 就是w2
            }
        }
        if(t1!=t2)
            return puts("-1"),0;//有的总和 与 要的总和不等 直接结束
        for(int i=1; i<=n-1; i++)
        {
            int u=read(),v=read();
            mp[u].push_back(v);
            mp[v].push_back(u);
        }
        dfs(1,0);
        ans=p[1].a*min(s1[1],s2[1])*2;//直接拿根节点去搞答案
        for(int i=0; i<mp[1].size(); i++)
        {
            int v=mp[1][i];
            dfs2(v,1,p[1].a);
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    移动端div移动
    js获取网页高度
    css cursor 的可选值(鼠标的各种样式)
    HTML5 拖动
    函数式编程中的常用技巧
    CoolShell Puzzle攻略[更新隐藏剧情]
    Web性能测试-词汇
    STM32库函数 断言机制 宏定义assert_param(expr)和assert_failed的使用方法
    arm汇编:伪指令ldr分析
    Altium designer 16 Mechanical1层之PCB 打样说明
  • 原文地址:https://www.cnblogs.com/QingyuYYYYY/p/13026957.html
Copyright © 2011-2022 走看看