杨八方的商业互吹(并查集)

说起大学生活,社团肯定是其中难忘的一部分。每年的招新季也是各个社团着力宣传自己的大好时机,然而“王婆卖瓜,自卖自夸”的宣传手段肯定难以服众。于是社团们之间往往有着很多交流与协作,杨八方称之为“商业互吹”(当然这是调侃的说法)。

兄弟社团们之间在给新生宣传时,可以通过互捧得方式让两个社团的名誉都有更好的发展。建立兄弟社团关系会使得在同学心目中捆绑成一个集体,有时候也是一荣俱荣一损俱损。

杨八方在选择社团的时候考虑到了这个问题,她在心目中给学校每个社团都评价了一个分数。如果两个社团成为了兄弟社团,那么对他们的评价便成为两者的平均值。如果A社团与B社团是兄弟社团,B社团与C社团是兄弟社团,那么A社团与C社团也将成为兄弟社团,杨八方对他们的评分便是三者的平均值,以此类推。

现在给出杨八方对每个学校社团的评分以及社团之间的兄弟关系,请输出在杨八方心目中社团最高的评分。

输入

第一行是两个正整数n、m,分别代表社团的个数及兄弟关系个数。

第二行是n个以一个空格隔开的整数ai,代表杨八方初始对i社团的评分(下标从1开始)。

下面m行每行有两个整数x、y,代表x社团和y社团是兄弟社团。

0<n≤106

0<m≤105

0≤ai≤104

输出

请输出杨八方心目中的最高评分,结果保留两位小数。

样例

input

5 3
1 2 3 4 5
1 2
4 5
2 3

output

4.50
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int father[1000010];
int num[1000010];
int val[1000010];
int wei[1000010];
int find(int x)
{
	if(x==father[x]) return x;
	else return father[x]=find(father[x]);
}
void join(int x,int y)
{
	x=find(x);y=find(y);
	if(x!=y) father[x]=y;
}
int main()
{
	int i;

	int n,t,c,d;
	scanf("%d%d",&n,&t);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&num[i]);
	 } 
	 for(i=1;i<=n;i++)
	{
		father[i]=i;
		val[i]=num[i];
		wei[i]=1;
	}
	 for(i=0;i<t;i++)
	 {
	 	scanf("%d%d",&d,&c);
	 	if(find(d)!=find(c))
	 	{
	 		join(c,d);
		 }
	 }
	 for(i=1;i<=n;i++)//这是关键,用空间换时间, 
     {
     	int m=find(i);
     	if(m!=i)
     	{
		 val[m]+=num[i];
     	wei[m]++;
		 wei[i]=0; }
	}
	 double ma=0,ll;
	 for(i=1;i<=n;i++)
	 {
	 	if(wei[i]!=0)
	 	{
	 		ll=val[i]/(wei[i]+0.0);
	 		if(ll>ma) ma=ll;
		 }
	 }
	 printf("%.2f\n",ma);
	return 0;
	
}

猜你喜欢

转载自blog.csdn.net/qq_42434171/article/details/85810568
今日推荐