带权并查集模板

题目:

题目描述
一个整数序列A{a0,a1,a2,....an-1},执行下列的操作:

  1. relate(x,y,z)表示ay比ax大z
  2. diff(x,y)打印输出ay-ax

输入

输出
打印操作输出值

样例输入
5 6
0 0 2 5
0 1 2 3
1 0 1
1 1 3
0 1 4 8
1 0 4

样例输出
2
?
10

code:

#include<cstdio>
using namespace std;
int fa[100005],val[100005];
int find(int x)
{
	if(fa[x]!=x)
	{
		int t=fa[x];
		fa[x]=find(fa[x]);
		val[x]+=val[t];
	}
	return fa[x];
}
int main()
{
	int n,q,tmp;
	scanf("%d%d",&n,&q);
	int pd,x,y,z;
	for(int i=0;i<n;i++)fa[i]=i;
	for(int i=1;i<=q;i++)
	{
		scanf("%d%d%d",&pd,&x,&y);
		if(pd==0)
		{
			scanf("%d",&z);
			int px=find(x);
			int py=find(y);
			if(px!=py)
			{
				fa[px]=py;
				val[px]=val[y]-val[x]+z;//注意这里的x,y和px之间的区别,不要弄混
			}
		}
		else
		if(pd==1)
		{
			if(find(x)!=find(y))
			{
				printf("?\n");
			}
			else
			printf("%d\n",val[x]-val[y]);
		}
	}
	return 0;
} 
posted @ 2019-07-29 13:50  ShineEternal  阅读(242)  评论(0编辑  收藏  举报