《算法竞赛进阶指南》0x07贪心 POJ2054 color the tree树的缩点与合并
标签:ref += turn ble 进阶 style 平均值 avg 图片
题目链接:http://poj.org/problem?id=2054
贪心算法,思路参考yxc,涉及树的合并与缩点,将所有触发点构成的链全部缩进根节点即可得到最终的结果。证明:
代码如下:
#includeusing 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){
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){
scanf("%d",&p[i].value);
p[i].avg=p[i].value;
p[i].cnt=1;
ans+=p[i].value;//动态维护结果
}
for(int i=0;i1;i++){//输入边
int u,v;
scanf("%d%d",&u,&v);
p[v].fa=u;
}
for(int i=0;i1;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){
if(p[j].fa==cur)//将cur结点的子节点接到fa结点上
p[j].fa=fa;
}
}
coutendl;
}
}
《算法竞赛进阶指南》0x07贪心 POJ2054 color the tree树的缩点与合并
标签:ref += turn ble 进阶 style 平均值 avg 图片
原文地址:https://www.cnblogs.com/randy-lo/p/13140640.html
评论