poj2054 Color a Tree
神题。这题是巨毒瘤...
自己写真可谓是:
排空驭气奔如电,上天入地求之遍
上穷碧落下黄泉,两处茫茫皆不见
由于我们知道:不是树形时,不停选值最大的节点可以得到最小代价。
那么我们就能想出一个错误的贪心:每次从能选的中选出最大的。
下面我们来构造反例:
root
↙ ↘
1 2
↓
100
贪心:2 + 2 + 300 = 304
实际:1 + 200 + 6 = 207
那么我们该如何处理呢?
完全搞不倒啊!看题解看题解
得出如下结论:最大的节点一定是紧随着父节点染色的。
下一步:没有下一步....?????
我们要把这两个节点合并!
等效权值为平均数!
很遗恨的是,我只会证明两个点时权值是平均数。更多的还有待考证...
不过做题就是要靠想象!这就是正确的!
所以我们在代码实现的难题上继续败北......
我的想法是每个节点记录所有子节点以及所有合并过来的节点的顺序。用两个vector来实现。
然后那个堆是最困扰我的地方,实现起来困难重重。
看一看标程:cnm!直接n²暴力!
1000 * 1000 ......我觉得还行
然后我还发现了一件事:它没有记录次序!合并的同时更新ans!
惊为天人!
代码要简洁高效。这一点在寒假时我就有体会,现在又有这种感觉。
/**
poj 2054
*/
#include <cstdio>
using namespace std;
typedef long long LL;
const int N = ;
const double eps = 1e-; struct Node {
int tot, n, fa;
bool del;
double val;
}node[N]; int n, R; inline int find() {
double maxval = -;
int ans = ;
for(int i = ; i <= n; i++) {
if(!node[i].del && i != R && node[i].val - maxval > eps) {
maxval = node[i].val;
ans = i;
}
}
return ans;
} inline int getfa(int k) {
while(node[k].del) {
k = node[k].fa;
}
return k;
} int main() {
scanf("%d%d", &n, &R);
while(n || R) {
LL ans = ;
node[R].fa = ;
for(int i = ; i <= n; i++) {
scanf("%d", &node[i].tot);
node[i].val = (double)node[i].tot;
node[i].n = ;
node[i].del = ;
ans += node[i].tot;
}
for(int i = ; i < n; i++) {
int x, y;
scanf("%d%d", &x, &y);
node[y].fa = x;
}
//printf("\n");
for(int i = ; i < n; i++) {
int s = find();
int f = getfa(node[s].fa);
//printf("%d %d\n", s, f);
ans += node[f].n * node[s].tot;
node[f].n += node[s].n;
node[f].tot += node[s].tot;
node[f].val = (double)(node[f].tot) / node[f].n;
//printf("%f\n", node[f].val);
node[s].del = ;
}
printf("%I64d\n", ans);
scanf("%d%d", &n, &R);
}
return ;
}
AC代码
poj2054 Color a Tree的更多相关文章
- [POJ2054]Color a Tree (并查集+贪心)
POJ终于修好啦 题意 和UVA1205是同一题,在洛谷上是紫题 有一棵树,需要给其所有节点染色,每个点染色所需的时间是一样的都是11.给每个点染色,还有一个开销“当前时间×ci×ci”,cici是每 ...
- Poj2054 color a tree && [HNOI/AHOI2018]排列
https://zybuluo.com/ysner/note/1120723 题面 原题 某省选强化题 大致意思是给你一颗树,选父亲后才能选儿子. 每个点对答案的贡献为你在第几次选这个点 × 该点权值 ...
- $Poj2054\ Color\ a\ Tree\ $ 贪心
$poj$ $Description$ 一颗树有 $n$ 个节点,这些节点被标号为:$1,2,3…n,$每个节点 $i$ 都有一个权值 $A[i]$. 现在要把这棵树的节点全部染色,染色的规则是: 根 ...
- POJ 2054 Color a Tree
贪心.... Color a Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: ...
- Color a Tree[HDU1055]
Color a Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- Color a Tree HDU - 6241
/* 十分巧妙的二分 题意选最少的点涂色 使得满足输入信息: 1 x的子树涂色数不少于y 2 x的子树外面涂色数不少于y 我们若是把2转化到子树内最多涂色多少 就可以维护这个最小和最大 如果我们二分出 ...
- POJ 2054 Color a Tree解题报告
题干 Bob is very interested in the data structure of a tree. A tree is a directed graph in which a spe ...
- Color a Tree & 排列
Color a Tree 题目链接 好不可做?可以尝试一下DP贪心网络流.DP 似乎没法做,网络流也不太行,所以试一下贪心. 考虑全局中最大权值的那个点,如果它没父亲,那么一定会先选它:否则,选完它父 ...
- hdu 6241 Color a Tree 2017 CCPC 哈理工站 L
Bob intends to color the nodes of a tree with a pen. The tree consists of NN nodes. These nodes are ...
随机推荐
- CMake--变量
1.一般变量 1)CMake变量引用的方式 使用${}进行变量的引用.例如: ${PROJECT_NAME} #返回项目名称 在 IF 等语句中,是直接使用变量名而不通过${}取值. 2)cmake自 ...
- Linux上的一些基本常用命令
上传下载文件:// 首先安装lrzsz # yum -y install lrzsz // 上传文件,执行命令rz,会跳出文件选择窗口,选择好文件,点击确认即可.# rz // 下载文件,执行命令sz ...
- js关闭当前页
/*关闭当前页*/ function closeCurrentPage() { var userAgent = navigator.userAgent; if (userAgent.indexOf(& ...
- 对于修改jsp页面后页面不发生变化的解决方法
1.清除 Tomcat 6.0\work\Catalina\localhost 里面这个工程的内容:2.清除 Tomcat 6.0 webapps 里面的这个工程内容,然后重新部署,重启服务器:3.清 ...
- Struts2——通配符,Action Method_DMI
Action wildcard 通配符(配置量降到最低) 使用通配符,就是为了配置简便,但是一定遵守“约定优于配置”原则,约定就是做项目之前最好事先与项目组的人或是自己规定好命名规则. 多个* {1 ...
- 老男孩python学习自修第十二天【常用模块之生成随机数】
常用函数 import random random.random() 生成0到1之间的小数 random.randint(begin, end) 生成[begin, end]之间的整数 random. ...
- 一、Composer
一.Composer -依赖管理工具 Composer 会帮你安装这些依赖的库文件
- MySQL创建远程用户并授权
今天需要在本地测试系统功能,因为本地没有数据库,就需要在程序里面连接远程数据库: 先用ssh登录远程服务器,用root连上数据库看看情况: mysql> select Host,User,Pas ...
- JUC同步锁(五)
根据锁的添加到Java中的时间,Java中的锁,可以分为"同步锁"和"JUC包中的锁". 一.同步锁--synchronized关键字 通过synchroniz ...
- SQL Server 一张图让你秒懂联合表查询