# include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int father[1010]; int next[1010];//当前集合的下个元素(包含i) int pre[1010];//当前集合的上个元素(包含i) int num[1010];//num[i]当前集合储存的点的个数(包含i) int vis[1010]; int sum[1010];//当前集合的元素和 int c[1010];//点的花费 int n,r; int find_max()//找到当前权值最大的集合 { double max=0; int bh=-1; for(int i=1;i<=n;i++) { if(max<(sum[i]*1.0)/num[i]&&!vis[i]) { max=(sum[i]*1.0)/num[i]; bh=i; } } return bh; } void uni(int x)//联合 { int i; for(i=father[x];pre[i]!=-1;i=pre[i])//找到父元素所在的集合 {} sum[i]+=sum[x]; num[i]+=num[x]; for(i=father[x];next[i]!=-1;i=next[i])//找到父元素所在集合的底元素 {} next[i]=x; pre[x]=i; vis[x]=1; } int main() { int i; while(~scanf("%d%d",&n,&r),n+r) { for(i=1;i<=n;i++) { scanf("%d",&c[i]); vis[i]=0; sum[i]=c[i]; pre[i]=next[i]=-1; num[i]=1; } for(i=1;i<n;i++) { int a,b; scanf("%d%d",&a,&b); father[b]=a; } int d; vis[r]=1;//初始点 while(1) { d=find_max(); if(d==-1) break; uni(d); } int ans=0,t=1; for(i=r;i!=-1;i=next[i]) { ans+=c[i]*t; t++; } printf("%d\n",ans); } return 0; }
版权声明:本文博客原创文章,博客,未经同意,不得转载。
时间: 2024-10-26 01:42:49