# Codeforces - 1363e tree shuffling

Keywords: Attribute iOS

Main idea: give a tree with root, the root node is point 1, each node has a weight val and two attributes b, c. The weights of attributes b and C are not 0, i.e. 1. Now you can select a node x, and then select any k nodes from the subtree. Reassign attribute b of these K nodes at the cost of val [x] * K. ask how much the minimum cost of making attribute b of all nodes equal to attribute C is

Problem analysis: after three days' delay in problem solving, I was tortured by the competition, final defense and digital analog test. Finally, I have time to do the problem again and write a blog to relax

First of all, for this tree, maintain the minimum value of point weight from top to bottom, because node fa is the ancestor of node u. if val [u] > val [fa], because the subtree of u must also be the subtree of fa, it is obvious that in fa, it is better to select the k nodes that are originally planned to be selected in U, so it is better to directly maintain val as the minimum value of ancestor

In this way, from the bottom up, count how many zeros in the subtree need to be changed into 1, which is recorded as c0. Similarly, count c1 as how many ones need to be changed into 0, and then greedy exchange is good

Note that if the quantity of 0 1 in b and c is not equal, you can output - 1 directly

code:

```#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;

typedef long long LL;

typedef unsigned long long ull;

const int inf=0x3f3f3f3f;

const int N=2e5+100;

struct Node
{
int a,b;
Node()
{
a=b=0;
}
Node(int a,int b):a(a),b(b){}
Node operator+(const Node& t)const
{
return Node(a+t.a,b+t.b);
}
Node operator-(int val)const
{
return Node(a-val,b-val);
}
int get_min()
{
return min(a,b);
}
};

int a[N],b[N],c[N];

vector<int>node[N];

LL ans=0;

Node dfs(int u,int fa)
{
Node temp;
if(b[u]!=c[u])
{
if(b[u]==1)
temp.a++;
else
temp.b++;
}
for(auto v:node[u])
{
if(v==fa)
continue;
a[v]=min(a[v],a[u]);
temp=temp+dfs(v,u);
}
int mmin=temp.get_min();
temp=temp-mmin;
ans+=2LL*mmin*a[u];
return temp;
}

int main()
{
#ifndef ONLINE_JUDGE
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);
#endif
//	ios::sync_with_stdio(false);
int n,c0=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",a+i,b+i,c+i);
c0+=(b[i]==0)-(c[i]==0);
}
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
node[u].push_back(v);
node[v].push_back(u);
}
if(c0)
return 0*puts("-1");
dfs(1,-1);
printf("%lld\n",ans);

return 0;
}```

Posted by 0riole on Thu, 04 Jun 2020 08:16:17 -0700