《算法竞赛进阶指南》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;
}
} 相关推荐
Tips 2020-11-12
troysps 2020-08-18
Eduenth 2020-07-17
RememberMePlease 2020-06-26
Happyunlimited 2020-06-11
RememberMePlease 2020-06-07
从零开始 2020-05-31
路漫 2020-05-07
Happyunlimited 2020-05-01
从零开始 2020-04-30
ustbfym 2020-04-30
清溪算法 2020-04-22
baike 2020-04-15
pengkingli 2020-03-28
baike 2020-03-27
shawsun 2020-02-26
faiculty 2020-02-24
ipqtjmqj 2020-01-23
alicelmx 2020-01-23