ABC372:K-th Largest Connected Components(并查集启发式合并)

问题陈述

有一个无向图,图中有 NN 个顶点和 00 条边。顶点编号为 11 至 NN 。

您会收到 QQ 个查询,需要按顺序处理。每个查询都属于以下两种类型之一:

  • 类型 11 :以 1 u v 格式给出。在顶点 uu 和 vv 之间添加一条边。
  • 类型 22 :格式为 2 v k.打印与顶点 vv 连接的顶点中 kk /th 最大的顶点编号。如果连接到顶点 vv 的顶点少于 kk ,则打印 -1

做法

本题就是建立集合,然后求集合中的第k大数。我们自然而然想到并查集来维护集合,而因为k很小,我们直接暴力求就好。

#include<bits/stdc++.h> 
using namespace std;

const int N=2e5+10;
int n,q,fa[N];

int getfa(int x){
	if(x==fa[x]) return x;
	else return fa[x]=getfa(fa[x]);
}

void setfa(int x,int y){
	fa[getfa(x)]=getfa(y);
}
int main(){
	
	scanf("%d%d",&n,&q);
	
	vector<set<int> > g(n+1);
	
	for(int i=1;i<=n;i++){
		g[i].insert(i);
		fa[i]=i;
	}
	
	while(q--){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		
		if(a==1){
			
			int u=getfa(b),v=getfa(c);
			
			if(u==v) continue;//不加会超时 
			
			if(u>v) swap(u,v);
			
			for(auto x:g[u]) g[v].insert(x);
			
			setfa(u,v);//小的集合加到大的集合里 
			
		}
		
		else{
			
			int u=getfa(b);
			
			if(g[u].size()<c) cout<<-1<<endl;
			
			else{//数据范围很小 ,可以直接暴力求 
				auto it=g[u].end();
				while(c--) it--;
				cout<<*it<<endl;
			}
			
		}
	}
}

wa的原因

1.合并集合的时候,没有用并查集合并两个集合。而是用vector来存每个点所连接的点,忽略了两个点代表的是两个集合,两个集合中不可能只有单单这两个点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值