[Ybtoj Chapter 10 Example 3] The Legend of the Galaxy Heroes [Consolidated Collection]

Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here


Problem-solving ideas

This question introduces an extended usage of union search set: sideband weighted union search set.

The edge weight here can represent a lot of information, such as the distance between a certain node and its parent node, or the sum of values ​​and the sum of exclusive ORs. . The general approach is similar to that of ordinary union search, but the edge weights must be updated when merging sets and path compression.

Back to this question, we can use the union to check whether the maintenance battleships are in the same row, with the first battleship in each row as the representative of the collection, use dis disd i s record the edge right,disx dis_xdisxRepresents the battleship numbered x to the numbered fax fa_xf axThere are several battleships (not including x) among the battleships, and maintain a num num at the same timen u m array,numx num_xn u mxIndicates how many warships there are in the collection with x as the representative element.
For query operations, we first judge x, yx, yWhether x and y are in the same column (and whether the representative elements of the set are the same), find out how many warships there are between them and the representative element, and the difference obtained by subtraction is the answer.


Code

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<bitset>
using namespace std;

int  T,x,y,fa[30010],num[30010],dis[30010];
char c;

int find(int x)
{
    
    
	if(fa[x]==x)return fa[x];	
	int v=find(fa[x]);
	dis[x]=dis[fa[x]]+dis[x];//自己到新爸爸的距离,等于自己的原爸爸到新爸爸的距离,加上自己到原爸爸的距离
	return fa[x]=v;
}

int main(){
    
    
	scanf("%d",&T);
	for(int i=1;i<=30009;i++)
		fa[i]=i,num[i]=1;
	while(T--)
	{
    
    
		cin>>c;
		scanf("%d%d",&x,&y);
		int xx=find(x),yy=find(y);
		if(c=='M')
		{
    
    
			fa[xx]=yy;
			dis[xx]=num[yy];//加上到新爸爸的距离(新增距离相当于新爸爸所在集合的长度)
			num[yy]+=num[xx];//加上新合并进来的长度
			num[xx]=0;//不存在了,被合并了
		}
		if(c=='C')
		{
    
    
			if(xx!=yy) printf("-1\n");
			else printf("%d\n",abs(dis[y]-dis[x])-1);//两飞船间距离
		}
	}
}

Guess you like

Origin blog.csdn.net/kejin2019/article/details/115212348