公司竞争(并查集)

公司竞争(并查集)

学长毕业啦!

学长自己开了一家大公司,现在很多公司选择了联盟。所以当决定和一家公司竞争的时候就要和联盟内所有公司竞争。

盟友关系是有传递性的。即 A 和 B 成为盟友,那么就会和 B 现有的其他盟友也成为盟友。

每个公司都有势力值。而联盟的势力值是所有联盟内公司的总和。

输入格式
第一行有两个数 n和 m。(1≤n,m≤10^5)
第二行有
n个整数,代表每个公司的势力值,不超过 10^3。
以后 m行代表 m 个事件:1 x y代表公司 x和公司 y结盟。
2 x 代表学长询问公司 x 所在的联盟的势力值。
输出格式
对于每一次询问输出一行,为所在的联盟的势力值。

Sample Input

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

Sample Output

3
5
6

思路: 经典并查集,不好写的地方为如何累加势力值,代码解释

AC代码:

#include<stdio.h>
#include<string.h>
int e[110000],f[110000],n,m;
void init()
{
	int i;
	for(i=1; i<=n; i++)
		f[i]=i;
}
int  find(int x)
{
	if(f[x]==x)
		return x;
	else
		return f[x]=find(f[x]);
}
void merge(int x,int y)
{
	int xx,yy;
	xx=find(x);
	yy=find(y);
	if(xx!=yy)
	{
		f[yy]=xx;
		e[xx]=e[xx]+e[yy];//只把综合势力值赋值给head,以防少加,多加
	}
}
int main()
{
	int i,j,k,c,a,b;
	scanf("%d%d",&n,&m);
	init();
	for(i=1; i<=n; i++)
		scanf("%d",&e[i]);
	while(m--)
	{
		scanf("%d",&c);
		if(c==1)
		{
			scanf("%d%d",&a,&b);
			merge(a,b);
		}
		if(c==2)
		{
			scanf("%d",&k);
			int x=find(k);//寻找k的head,输出head的势力值
			printf("%d\n",e[x]);
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值