CF771A. Bear and Friendship Condition 題解 並查集

quanjun發表於2024-10-26

題目連結:https://codeforces.com/problemset/problem/771/A

影片講解:https://www.bilibili.com/video/BV1tZ1FYPELp/?p=6

題目大意:判斷一個無向圖中的每個連通塊是否都是一個完全圖。

首先我們可以用並查集維護每個連通塊的大小。

其次,我們可以開一個 \(cnt_i\) 表示以節點 \(i\) 為根的連通塊中包含多少條邊。

則對於每個連通塊的根節點 \(i\),必須滿足 \(\frac{ sz_i \times (sz_i - 1) }{2} = cnt_i\) 才是 YES;否則,是 NO。(這裡 \(sz_i\) 表示以 \(i\) 為根的連通塊的大小,即這個連通塊中的節點個數)

示例程式:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1.5e5 + 5;
int n, m, f[maxn], sz[maxn], cnt[maxn];
struct Edge {
	int u, v;
} e[maxn];

void init() {
	for (int i = 1; i <= n; i++)
		f[i] = i, sz[i] = 1;
}

int find(int x) {
	return x == f[x] ? x : f[x] = find(f[x]);
}

void funion(int x, int y) {
	int a = find(x), b = find(y);
	if (a != b) {
		f[b] = a;
		sz[a] += sz[b];
	}
}

int main() {
	scanf("%d%d", &n, &m);
	init();
	for (int i = 0; i < m; i++) {
		scanf("%d%d", &e[i].u, &e[i].v);
		funion(e[i].u, e[i].v);
	}
	for (int i = 0; i < m; i++) {
		cnt[find(e[i].u)]++;
	}
	for (int i = 1; i <= n; i++) {
		if (i == find(i)) {
			if ((long long)sz[i] * (sz[i] - 1) / 2 != cnt[i]) {
				puts("NO");
				return 0;
			}
		}
	}
	puts("YES");
	return 0;
}

相關文章