并查集最大连通块大小D. Social Network

Posted 行码棋

tags:

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

题目链接:
https://codeforces.com/problemset/problem/1609/D

题意看了好长时间,看不懂,英语太难了😭😭😭

d个条件,到达第i个条件时,要保证前i个条件中的xy是连通的(不是必须相连),且图中需要共有i条边,求最大连通块的大小

也就是说,如果之前的条件已经让xy连通了,这次没必要再连接xy了,可以自由支配连接一条边


对于每次询问xy

询问x和y x和y不连通 x和y连通 让x和y相连 可自由连接边数cnt++ 结果统计 所有连通块大小加入ve数组 从大到小排序 利用自由边对大的连通块进行连接

最后结果为res-1,除去本身


cnt:代表可以自由连接边的条数
ve[]:代表所有连通块大小的数组,之后会对其进行从大到小排序

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int N = 1e5+5;


struct dsu

	vector<int>f,sz; 
	dsu(int n)
	
		f.resize(n);
		sz.resize(n,1);
		for(int i=0;i<n;i++) f[i] = i;
			
	void merge(int x,int y)
	
		x = find(x);
		y = find(y);
		if(x == y) return; 
		if(x > y) swap(x,y);
		f[y] = x;
		sz[x] += sz[y];
		sz[y] = 0;
	
	int find(int x)
	
		return f[x]==x ? x : f[x]=find(f[x]);
	
;

void solve()

	int n,m;
	cin>>n>>m;
	dsu tr(n+1);
	int cnt = 0;

	while(m--)	
	
		int u, v;
		cin>>u>>v;
		int x = tr.find(u);
		int y = tr.find(v);
		if(x == y) cnt ++;
		else tr.merge(x,y);
		
		vector<int> ve;
		for(int i=1;i<=n;i++)
			if(tr.sz[i]) ve.push_back(tr.sz[i]);	
			
		sort(ve.begin(),ve.end(),greater<int>());
		int res = 0;
		for(int i=0;i<=cnt and i<ve.size();i++)
			res += ve[i];
		cout<<res - 1<<endl;
	


int main()

	int t;
//	cin>>t;
	t = 1;
	while(t--) solve();
	return 0;

以上是关于并查集最大连通块大小D. Social Network的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces - 1253D(并查集)

Codeforces Round #747 (Div. 2) D. The Number of Imposters(并查集,二分图)

Codeforces Round #747 (Div. 2) D. The Number of Imposters(并查集,二分图)

CodeForces827 D. Best Edge Weight 最小生成树+倍增LCA+并查集

loj6198谢特 后缀数组+并查集+Trie

D. Cow and Snacks 并查集