牛客网-第一题【并查集统计联通子图】

牛客网-第一题【并查集统计联通子图】_第1张图片
顶点的多少没有给出来,1000000是一个可以AC的范围,每次输入一对点,我们就将其归为一类,即并查集的unite操作,最后只需要统计并查集中有多少个元素满足kind[i]==i,这个条件即标识着一个新的联通子图。

#define inf 0x3ffffff
#define ll int
#define MAX 1000005
#define vec vector

ll exist[MAX], kind[MAX];

ll find(ll k) {
	if (k == kind[k])return k;
	else return kind[k] = find(kind[k]);
}

void unite(ll a, ll b) {  kind[find(b)] = kind[find(a)]; }

int main() {
	ll a, b, N = 0, res = 0;
	for (int i = 0; i < MAX; i++)kind[i] = i;
	memset(exist, 0, sizeof(exist));
	while (cin >> a >> b) {
		N = max(max(a, b), N);
		exist[a] = exist[b] = 1;
		unite(a, b);
	}
	for (int i = 1; i <= N; i++) {
		if (!exist[i])continue;//这个节点不存在
		if (kind[i] == i)res++;//并查集性质,kind[i]==i就是一个新的种群
	}
	cout << res << endl;
}

你可能感兴趣的:(牛客网)