zoukankan      html  css  js  c++  java
  • CF-1363E Tree Shuffling【树上贪心】

    题意:

    给出一棵 (n)个节点的树,每个节点有三个值:(a[i],b[i],c[i]),分别为该点的花费,该点的当前状态,该点的目标状态。
    每次可以选择点 (u) 的子树中的 (k) 个点,将它们的当前状态进行重新排序,使之达到目标状态,花费为 (k*a[u])。求出最小的花费,使得所有的点达到目标状态。
    数距范围:(1≤n≤2⋅10^5,1≤a_i≤10^9,0≤b_i,c_i≤1)

    分析:

    把最小值按路径从上到下传递下去,如果当前点的花费不大于祖先中的最小花费,那么可以以该点为根进行处理。

    代码:

    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int N=2e5+5;
    const int inf=0x3f3f3f3f;
    vector<int>pic[N];
    int a[N],b[N],c[N],num[N][2];
    int n;
    ll ans;
    void dfs(int v,int p,int minn)
    {
        if(b[v]!=c[v])
        {
            if(b[v]==0) num[v][0]++;
            else num[v][1]++;
        }
        for(int i=0;i<pic[v].size();i++)
        {
            int u=pic[v][i];
            if(u==p) continue;
            dfs(u,v,min(minn,a[v]));
            num[v][0]+=num[u][0];
            num[v][1]+=num[u][1];
        }
        if(minn>=a[v])//保证贪心
        {
            int t=min(num[v][0],num[v][1]);
            ans+=2LL*t*a[v];
            num[v][0]-=t;
            num[v][1]-=t;
        }
    }
    int main()
    {
        int u,v;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d%d%d",&a[i],&b[i],&c[i]);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            pic[u].pb(v);
            pic[v].pb(u);
        }
        ans=0;
        dfs(1,0,inf);
        if(num[1][0]||num[1][1])
            printf("-1
    ");
        else
            printf("%lld
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    线程与进程
    Java集合框架体系JCF
    Java异常
    抽象,接口和Object类
    Java三大特性
    面向对象
    数组
    Java 控制结构与方法
    数据类型与变量
    Java基础之入门
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13038882.html
Copyright © 2011-2022 走看看