《算法竞赛进阶指南》0x07贪心 POJ2054 color the tree树的缩点与合并
Posted randy-lo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法竞赛进阶指南》0x07贪心 POJ2054 color the tree树的缩点与合并相关的知识,希望对你有一定的参考价值。
题目链接:http://poj.org/problem?id=2054
贪心算法,思路参考yxc,涉及树的合并与缩点,将所有触发点构成的链全部缩进根节点即可得到最终的结果。证明:
代码如下:
#include<iostream> using namespace std; const int maxn= 1010; struct Node{ int fa,cnt,value;//维护父节点,结点数量以及缩点内的和,平均值 double avg; }p[maxn]; int root ,n; int find(){//查找下一个均值最大点 double avg=0; int res=-1; for(int i=1;i<=n;i++){ if(i!=root && p[i].avg>avg){ avg=p[i].avg; res=i; } } return res; } int main(){ while(cin>>n>>root && n && root){ int ans=0; for(int i=1;i<=n;i++){ scanf("%d",&p[i].value); p[i].avg=p[i].value; p[i].cnt=1; ans+=p[i].value;//动态维护结果 } for(int i=0;i<n-1;i++){//输入边 int u,v; scanf("%d%d",&u,&v); p[v].fa=u; } for(int i=0;i<n-1;i++){//每次合并两个点,合并n-1次收敛为一个点 int cur=find(); int fa=p[cur].fa; ans+=p[fa].cnt*p[cur].value; p[cur].avg=-1;//表示当前点已经从图中删除,这个点将不会再使用 p[fa].value+=p[cur].value; p[fa].cnt+=p[cur].cnt; p[fa].avg=(double)p[fa].value/p[fa].cnt; for(int j=1;j<=n;j++){ if(p[j].fa==cur)//将cur结点的子节点接到fa结点上 p[j].fa=fa; } } cout<<ans<<endl; } }
以上是关于《算法竞赛进阶指南》0x07贪心 POJ2054 color the tree树的缩点与合并的主要内容,如果未能解决你的问题,请参考以下文章
《算法竞赛进阶指南》0x43线段树 扫描线算法 POJ2482
《算法竞赛进阶指南》0x27A* 八数码问题 POJ1077
《算法竞赛进阶指南》0x15 POJ1961 KMPNext数组求循环节