题目链接

题目大意

给你一颗树,每一个节点有一个a[i],b[i],c[i]值,你要把b[i]变成c[i],b[i]和c[i]为[0,1],你操作的方法是,选择一个节点x,选择他的k个子树,然后进行交换他们的b[i]值,使满足要求,每次操作的cost为a[x]*k,求满足题目要求所需要的最小cost,如果不能满足要求,则输出-1.

题目思路

基本思路想到了,但是不会实现,码力太差,直接放标准解析。

Key Idea: Let the parent of node i be p. If a[i]≥a[p], we can do the shuffling which was done at i, at p instead. Thus, we can do the operation a[i]=min(a[i],a[p]).

Detailed Explanation: Let us denote nodes that have bi=1 and ci=0 as type 1, and those that have bi=0 and ci=1 as type 2. Firstly, the answer is −1 if and only if the number of nodes of type 1 and type 2 are unequal.

We also observe that only nodes of type 1 and 2 should be shuffled - it is unoptimal to shuffle those which already have b[i]=c[i]. Thus, we should try to exchange the values of type 1 and type 2 nodes.

We use the key idea by going down from the root, and at every node i, setting a[i]=min(a[i],a[p]) where p is the parent node of i in the tree. Thus, the a[i]'s now follow a special structure: they are non-increasing from the root to the leaves!

This paves the way for our greedy solution: we will go upwards from the leaves, and at each node i interchange type 1 and type 2 nodes until we have no nodes in one of these types. Then, we pass on the remaining nodes to the parent to be shuffled.

代码

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
int n,a[maxn],b[maxn],c[maxn],head[maxn],cnt;
ll cost;
struct node{int to,next;
}e[maxn<<1];
void add(int u,int v){e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;
}
pair<int,int> dfs(int son,int fa,int mi){pair<int,int> x;x.first=x.second=0;if(b[son]==1&&c[son]==0){x.first++;}else if(b[son]==0&&c[son]==1){x.second++;}for(int i=head[son];i;i=e[i].next){if(e[i].to!=fa){pair<int,int> y=dfs(e[i].to,son,min(mi,a[son]));x.first+=y.first;x.second+=y.second;}}if(a[son]<=mi){int take=min(x.first,x.second);cost+=1ll*2*take*a[son];x.first-=take;x.second-=take;}return x;
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d %d %d",&a[i],&b[i],&c[i]);}for(int i=1,u,v;i<=n-1;i++){scanf("%d %d",&u,&v);add(u,v),add(v,u);}pair<int,int> ans=dfs(1,1,a[1]);if(ans.first==0&&ans.second==0){printf("%lld\n",cost);}else{printf("-1\n");}return 0;
}

Codeforces Round #646 (Div. 2)E. Tree Shuffling 题解(dfs)相关推荐

  1. Codeforces Round #646 (Div. 2) E(贪心,bfs)

    Codeforces Round #646 (Div. 2) E 题目大意: 给一棵树,每个节点有三个权值 A,B,C, (B,C为0或1),每次你可以花费 A[u] *k的代价让A子树中的任意 k ...

  2. Codeforces Round #807 (Div. 2)A~E个人题解

    Dashboard - Codeforces Round #807 (Div. 2) - Codeforces A. Mark the Photographer 题意: 有个人,每个人的身高设为,现在 ...

  3. Codeforces Round #731 (Div. 3) G. How Many Paths? dfs + 拓扑 + 思维

    传送门 题意: 给你一张nnn个点mmm条边的图,让你对每个点确定一个编号,规则如下: (1)(1)(1) 对于不能到的点编号为000. (2)(2)(2) 对于只有一条路径能到这个点的点编号为111 ...

  4. Codeforces Round #706 (Div. 2)-A. Split it!-题解

    目录 Codeforces Round #706 (Div. 2)-A. Split it! Problem Description Input Output Sample Input Sample ...

  5. Codeforces Round #742 (Div. 2) B、C 题解

    Codeforces Round 742 B. MEXor Mixup 题意 有一个数组,输入两个数a,b,a代表这个数组之外的最小非负整数,b代表这个数组的异或值,问你该数组的最小长度. 思路 首先 ...

  6. Codeforces Round #308 (Div. 2) C. Vanya and Scales dfs

    题目链接: http://codeforces.com/contest/552/problem/C 题意: 给你100个砝码,第i个砝码质量是w^i,然后问你能不能在有m的情况下,左边和右边都放砝码, ...

  7. Codeforces Round #316 (Div. 2) D. Tree Requests dfs序

    题目链接: 题目 D. Tree Requests time limit per test:2 seconds memory limit per test:256 megabytes 问题描述 Rom ...

  8. Codeforces Round #506 (Div. 3) - E. Tree with Small Distances

    题目链接 题意 给你一棵树,最多加几条边,使点1到所有的点的最大距离不超过2 AC 贪心 从距离最远的点开始,找到他的父节点,然后把父节点相连的点删去,这样最好的情况可以删除三层点 遍历树的时候有两种 ...

  9. Codeforces Round #321 (Div. 2) C. Kefa and Park dfs

    C. Kefa and Park Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/580/probl ...

最新文章

  1. 布尔类型和三目运算符
  2. BZOJ4589: Hard Nim(FWT 快速幂)
  3. c语言ffffff错误,C语言打印16进制出现0xffffff现象的问题剖析!
  4. 52个实用的数据可视化工具!
  5. [C#]打包项目[转]
  6. 通过java.net.URLConnection发送HTTP请求的方法
  7. 面对女人的喋喋不休时,男人内心的真实想法
  8. Python 绘制热力图参数详解
  9. hhkb mac设置_把 HHKB 放在 MacBook 上使用的解决方案
  10. python 行为驱动_什么是行为驱动的Python?
  11. centos mysql5.6.35_centos6.8 mysql 5.6.35 glibc安装
  12. 软件测试国际化测试指标,国际化软件测试内容解析(2)
  13. JZOJ7月18日提高组T3 Ocd
  14. ioncube linux,linux 下ionCube安装
  15. 100以内的质数(基础算法)
  16. 宾州州立计算机科学世界排名,美国宾州州立大学排名和各专业排名
  17. excel 中如何设置误差线以及其意义
  18. 中国最缺大学的重点城市
  19. C#制作一个简易抽奖或摇号器
  20. 哪里能找到搞笑自媒体素材?学会技巧才能提高创作效率

热门文章

  1. 学1个月爬虫就月赚6000?别被骗了,老师傅告诉你爬虫的真实情况.。
  2. VUE学习-脚手架vue cli(六)
  3. upx工具编译使用指导
  4. html中字体在上下边缘居中,图片与文字在一行上垂直居中的方法
  5. Java 读取Word文档中的文本内容
  6. excel组合汇总_Excel汇总20181025
  7. iOS 画图工具的截图
  8. 性能优化 -- 优化SurfaceView的线程调用
  9. 对于员工上班时间在电脑上炒股,玩游戏,开小差,管理者应该怎么管理呢?
  10. opencv入门基础(c++)【二】