运用的并查集思想来合并节点,样例过了,但是提交 WA 力,求助大佬帮忙调一下
#include<bits/stdc++.h>
using namespace std;
priority_queue< pair<double,int> > q;
int c[1100],fa[1100];
double eql[1100];
int nextD[1100];
int pre[1100],endD[1100];
int find(int x) // 并查集查祖先
{
if(pre[x]==x) return x;
return pre[x]=find(pre[x]);
}
void work(int n,int r)
{
int i,j;
bool f[1100]={};
int ans=0;
for(i=1;i<=n;i++)
{
scanf("%d",&c[i]);
eql[i]=(double)c[i];
nextD[i]=0;
pre[i]=endD[i]=i;
q.push(make_pair(eql[i],i));
}
for(i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
fa[y]=x;
}
while(q.size())
{
int x=q.top().second; q.pop();
if(f[x]||x==1) continue;
eql[fa[x]]=(eql[fa[x]]+eql[x])/2;
// 并查集思想合并
nextD[endD[find(fa[x])]]=x;
pre[x]=find(fa[x]);
endD[find(fa[x])]=endD[x];
q.push(make_pair(eql[fa[x]],fa[x]));
f[x]=true;
}
for(i=1,j=1;i!=0;i=nextD[i],j++)
ans+=c[i]*j;
printf("%d\n",ans);
}
int main()
{
int n,r;
while(scanf("%d%d",&n,&r)&&n&&r)
work(n,r);
return 0;
}