【0x40 数据结构进阶 例题】银河英雄传说【带权并查集】

题意:

N N N 艘战舰,一开始第 i i i 号战舰处于第 i i i 列。 M M M 条指令,两种形式。
①   M   i   j ①\ M\ i\ j  M i j ,表示让第 i i i 号战舰所在列的全部战舰保持原有顺序,接在第 j j j 号战舰所在列的尾部。
②   C   i   j ②\ C\ i\ j  C i j ,表示询问第 i i i 号战舰与第 j j j 号战舰当前是否处于同一列中,如果在同一列中,它们之间隔了多少艘战舰。
( N ≤ 30000 , M ≤ 5 ∗ 1 0 5 ) (N\leq 30000,M\leq 5*10^5) (N30000M5105)


思路:

典型的带权并查集题目,维护的是距离根节点的距离。
d [ x ] = x → r o o t d[x] = x\rightarrow root d[x]=xroot,表示x与根节点之间的距离。

查询 x → y x\rightarrow y xy 的距离,即 x → y = x → r o o t + r o o t → y = d [ x ] − d [ y ] x\rightarrow y=x\rightarrow root+root\rightarrow y=d[x]-d[y] xy=xroot+rooty=d[x]d[y],因此 x 、 y x、y xy 之间的距离为 a b s ( d [ x ] − d [ y ] ) abs(d[x]-d[y]) abs(d[x]d[y]),输出这个值即可。

再考虑集合合并。将 x x x y y y 进行合并,即 f a [ f x ] = f y , d [ f x ] = f x → f y = s i z e [ f y ] fa[fx] = fy,d[fx] = fx\rightarrow fy=size[fy] fa[fx]=fyd[fx]=fxfy=size[fy] s i z e [ f y ] size[fy] size[fy] 表示 f y fy fy 这个集合中的元素个数,我们在并查集中多维护一个集合大小即可。

至此,本题结束。


代码:

#include 
#include 
#include 
#include 
#include 
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
typedef long long ll;
typedef double db;
const db EPS = 1e-9;
using namespace std;
const int N = 3*1e4+1000;

int fa[N],d[N],size[N];

int find(int x){
     
	if(fa[x] == x) return x;
	int root = find(fa[x]);
	d[x] += d[fa[x]], size[x] = size[root];
	return fa[x] = root;
}

int main()
{
     
	int _; scanf("%d",&_); int base = 3*1e4;
	rep(i,0,base) fa[i] = i, d[i] = 0, size[i] = 1;
	while(_--)
	{
     
		char op[10]; int x,y;
		scanf("%s",op);
		if(op[0] == 'M'){
     
			scanf("%d%d",&x,&y);
			int fx = find(x), fy = find(y);
			fa[fx] = fy;
			d[fx] = size[fy];
			size[fy] += size[fx];
		}
		else{
     
			scanf("%d%d",&x,&y);
			int fx = find(x), fy = find(y);
			if(fx != fy) printf("-1\n");
			else{
     
				printf("%d\n",abs(d[x]-d[y])-1);
			}
		}
	}
	return 0;
}

你可能感兴趣的:(#,并查集,数据结构,带权并查集)