求助怎么绿
查看原帖
求助怎么绿
239192
淸梣ling楼主2021/9/26 19:43

运用的并查集思想来合并节点,样例过了,但是提交 WAWA 力,求助大佬帮忙调一下

#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;
}
2021/9/26 19:43
加载中...