加权并查集

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了加权并查集相关的知识,希望对你有一定的参考价值。

  加权并查集是一种特殊的并查集,除可提供查询操作外,还可用于表示元素与其代表元素的关系。下面以食物链为例,讲解一下加权并查集。

#include<cstdio> //调用cstdio库,使用getchar函数
#include<cctype> //调用cctype库,使用isdigit函数,返回参数是否为整数
int N,K,ans,r,x,y; //定义变量用于有几个动物,几句话,答案,以及动物的关系和两个要描述的动物 
int f[50005],d[50005]; //定义数组记录代表元素,以及到达代表元素的距离 
inline int get_num() { //内联get_num函数,读入整数
    int num = 0; //定义整型变量num,并赋值为0
    char c; //定义字符型变量c
    bool flag = false; //定义布尔值变量flag,并置为假
    while ((c = getchar()) == ‘ ‘ || c == ‘\n‘ || c == ‘\r‘); //忽略开头的空格,换行符及回车符
    if (c == ‘-‘) flag = true; //如果读到负号,就将负数标志置为真
    else num = c - ‘0‘;    //否则将读到的第一个数字保存;
    while (isdigit(c = getchar())) //只要读入的还是数字,就循环
        num = num * 10 + c - ‘0‘; //将num整体前移一位,并将新读入的一位数字保存
    return (flag ? -1 : 1) * num; //返回读到的整数,若负数标志为真,就返回其相反数,即一个负数
}
int find(int i) { //定义函数查询代表元素以及到达代表元素的距离 
	if(i==f[i]) return i; //找到代表元素返回 
	int oldf=f[i]; //记录下元素之前的代表元素
	f[i]=find(f[i]); //更新元素的代表元素 
	d[i]=(d[i]+d[oldf])%3; //更新元素与代表元素的距离 
	return f[i]; //返回代表元素 
}
void check(int r,int x,int y) { //定义函数检查是否为假话 
	if(x>N||y>N) {++ans;return;} //若动物编号超出范围,则为假话 
	if(r==2&&x==y) {++ans;return;} //若说动物自己吃自己,则为假话 
	if(find(x)==find(y)) { //若两个动物在同一集合中 
		if((d[x]-d[y]+3)%3!=r-1) ++ans;return; //动物之间的距离不符合描述,则为假话 
	}
	else {
		d[f[x]]=(3-d[x])%3; //求出代表元素到该元素的距离 
		f[f[x]]=x;f[x]=y; //让代表元素指向该元素,即该元素成为代表元素,并指向y 
		d[f[y]]=(3-d[y])%3; //同上 
		f[f[y]]=y;f[y]=y;d[y]=0; // 同上,并让y成为代表元素,令其到代表元素的距离为0 
		if(r==1) d[x]=0; //若为同类,则x到y距离为0 
		else d[x]=1; //若x吃y,则x到y距离为1 
		/* 另一种合并方法 
		f[f[y]]=f[x]; //让y的代表元素指向x的代表元素 
		d[f[y]]=(d[x]-d[y]-(r-1)+3)%3; //更新y的代表元素到其代表元素的距离 
		*/ 
	}
}
int main() {
	N=read();K=read(); //读入N,K 
	for(int t=1;t<=N;++t) f[t]=t; //初始化每个元素的代表元素 
	for(int t=1;t<=K;++t) { //遍历每句话 
		r=read();x=read();y=read(); //读入r,x,y
		check(r,x,y); //调用check函数 
	}
	printf("%d",ans); //打印答案 
	return 0;
}

 

以上是关于加权并查集的主要内容,如果未能解决你的问题,请参考以下文章

Zjnu Stadium(加权并查集)

加权并查集——(POJ1988)Cube Stacking

HDU 3407.Zjnu Stadium 加权并查集

Cube Stacking P0J 1988(加权并查集)

HDU3038(KB5-D加权并查集)

P1196 银河英雄传说(加权并查集)