$ POJ~2054~Color~a~Tree $



$ solution: $

我们先从题中抽取信息,因为每个点的费用和染色的次数有关,所以我们可以很自然的想到先给权值大的节点染色。但是题目还说每个节点染色前它的父亲节点也必须被染色,这就有了很多的后效性。

暂时没有办法贪心,我们就只能再找找性质。博主首先想到的是从叶子节点考虑,叶子节点里权值最小的一定最后染色。但是经过自我hack,这个结论也是错的。举个栗子:5-1-1-1-8,这条链上如果以左边第一个1为根,先染5会更优。

叶子节点我们拿他没办法,所以我们看看树枝,然后我们可以猜一个贪心:对于某一个节点,在它的所有儿子节点中最早被染色的一定是最大的那个。好吧,这个贪心也是错的,每个节点的费用会受到子节点的影响。

那,什么情况下不会有后效性呢?我们可以从全局考虑,找整颗树上权值最大的节点,这个节点一定在它父亲染色后第一个被染色。这个顺序绝不会变(是一个正确的贪心)。但是我们找到这个最大的节点之后又该如何?找第二大的节点?可这个结论还适用吗?

这里我们有一个常用套路,在之前贪心是我们其实就可以想到:对每个点设定一个新的权值。但是这个设新权值的办法在最开始不好用,它要猜。不过我们在想出上面这个贪心后就可以很容易设出来这个权值。因为上面说过了最大的节点一定在它父亲染色后第一个被染色。这,我们不就相当与将两个点合并吗?但是新权值怎么设?我们仔细思考一下就可以知道新权值为新节点所包含节点的权值和除以包含的节点数

然后我们直接按照这个方法贪心,找最大用优先队列,每次合并时计算一下局部答案即可。复杂度 $ O(nlogn) $



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>#define ll long long
#define db double
#define rg register intusing namespace std;db d[1005];
int n,root,top;
int s[1005];
int fa[1005];
int tot[1005];
int sum[1005];
int ans[1005];
bool use[1005];struct pi{db v; int id;inline bool operator <(const pi &x)const{return v<x.v;}
}a[1005];priority_queue<pi> q;inline int qr(){register char ch; register bool sign=0; rg res=0;while(!isdigit(ch=getchar()))if(ch=='-')sign=1;while(isdigit(ch))res=res*10+(ch^48),ch=getchar();if(sign)return -res; else return res;
}inline int get(int x){if(x==s[x])return x;return s[x]=get(s[x]);
}int main(){//freopen(".in","r",stdin);//freopen(".out","w",stdout);while(~scanf("%d%d",&n,&root)){if(!n&&!root)break;for(rg i=1;i<=n;++i){rg x=qr(); d[i]=a[i].v=x; a[i].id=i; q.push(a[i]); //读入s[i]=i; tot[i]=1; use[i]=0; sum[i]=ans[i]=x;//预处理} use[root]=1; //根节点没有父亲,不能合并,所以直接判它已被使用for(rg i=1;i<n;++i){rg x=qr(),y=qr(); fa[y]=x; //读入父子关系y}for(rg i=1;i<n;++i){ //有且仅有n-1次合并while(use[q.top().id]||d[q.top().id]!=q.top().v)q.pop();//有一些节点被用过,是无效的rg x=q.top().id,y=get(fa[x]); q.pop(); //x为儿子,y为父亲s[x]=y; use[x]=1; ans[y]+=ans[x]+sum[x]*tot[y]; //更新节点信息tot[y]+=tot[x]; sum[y]+=sum[x]; //更新节点信息pi z; d[y]=z.v=(db)sum[y]/tot[y]; z.id=y; q.push(z); //合并节点}printf("%d\n",ans[root]); //根节点的答案才是最终答案}return 0;
}

转载于:https://www.cnblogs.com/812-xiao-wen/p/11249682.html

POJ 2054 Color a Tree (贪心)相关推荐

  1. 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 ...

  2. POJ 2054 Color a Tree

    贪心....                    Color a Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions:  ...

  3. PKU/POJ 2054 Color a Tree

    关于树的着色. 要求从根节点出发, 遍历整棵树, 要求代价最小. 访问每个节点的代价V[i] = F[i] * C[i], C[i]为已知的值, F[i]则为访问该节点的时间. 每一步只能从已访问的节 ...

  4. POJ 2054 谜一样的贪心 TAT

    题意:给一个树形图(边为有向边的树),每个节点有一个权值Ci,要求给每个节点染色,要求是如果想对一个节点染色,那么必须保证它的父节点已经被染过色.求一个最小的染色代价,每个节点的代价是ki*Ci,ki ...

  5. UPC1430 Color a Tree(贪心)

    链接:http://exam.upc.edu.cn/problem.php?cid=1430&pid=19 题意: 一棵树,n个节点,n-1条边,每个节点有权值val.Time为当前时间,初始 ...

  6. HDU 6241 Color a Tree

    Color a Tree 题目大意:一棵树,根为1.某些点有一些限制.限制A: 该$x_i$点子树染色点至少$y_i$个. 限制B: 该$x_i$点子树外染色至少$y_i$个.求最少染色点数. 首先是 ...

  7. poj 3013 Big Christmas Tree(最短路变形)

    传送门:POJ 3013 Big Christmas Tree 描述: Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K To ...

  8. HDU_1055 POJ_2054 Color a Tree(贪心)

    这道题整了一下午,最后还是看别人的解题报告弄出来的,先说说我的理解吧.大体处理思路是利用贪心思想,每次取权值最大的节点,不断的将权值最大节点与它的父节点合并. 过程: 1.初始时将序列中的time[i ...

  9. poj 2777Count Color

    这道题,做的太悲催了,开始想到每个节点的涂色情况用数组来存,1代表有,0代表没有,提交上去果断RE了好几次,原因是here A, B, C are integers, and A may be lar ...

最新文章

  1. 手把手教你写一个Java的orm框架(4)
  2. 如何使用SkyDrive的25 GB作为映射驱动器以方便访问
  3. python每秒20个请求_使用Python每秒百万个请求
  4. LeetCode 611. 有效三角形的个数(双指针)
  5. 【Cisco技术资料汇总】
  6. 天津市七下计算机课程,七年级下册信息技术课程教案.doc
  7. linux中,一个目录的权限是777,普通用户为什么删除不了它呢?
  8. 使用Microsoft数据迁移助手将Oracle数据库迁移到SQL Server –安装过程和简短概述
  9. HUE与YARN的集成
  10. hibernate4 could not initialize proxy - no Session
  11. python3基础(九)内置函数
  12. 利用Matlab寻找曲线的拐点
  13. vs2005 编码转换后编译的时候会出错,”error c101008a“,处理方法
  14. 已失效:TeamView被检测到 商业行为
  15. 二十五个软件测试经典面试题
  16. 非形式逻辑(01)概念及其种类
  17. WDS服务--网络安装系统(自动部署装机Windows系统)
  18. Debian下的搜狗拼音安装个人心得
  19. 【Qt】解决 “由于找不到Qt5Cored.dll,无法继续执行代码”(亲测有效)
  20. 第九届河南省程序设计大赛-NYOJ-1276(搜索batter)

热门文章

  1. 捋一捋js面向对象的继承问题
  2. 15、iOS开发之duplicate symbols for architecture x86_64错误
  3. 关于系统性能检测的一些使用
  4. Jan 12 - Delete Node in a Linked List; Data Structure; Linked List; Pointer;
  5. 欧拉函数 - HDU1286
  6. koa --- 跨域,解析POST参数、路由配置
  7. Jacoco--测试覆盖率工具
  8. 徐小平:全员拥抱区块链是内部分享 1比特币寻泄密者
  9. abstract class 和 interface 区别
  10. [译]多线程网络服务模型