반응형

 

유니온 파인드로 트리인지 판별해주었습니다.

간선을 생성하는 두 노드의 부모가 같은 그룹이 아니라면, 같은 그룹으로 묶어줍니다.

이미 같은 그룹이라면, 사이클이 발생한 것입니다.

따라서 해당 부모 노드를 부모로 가지는 그룹은 트리를 구성할 수 없습니다.

또, 아직 같은 그룹이 아니더라도 이미 기존의 그룹이 사이클을 형성한 상태였으면, 새롭게 그룹에 들어오는 노드도 트리를 형성할 수 없는 그룹입니다.

 

#include <cstdio>
#include <cstring>
#define INF 2147483647

int n, m, a, b, cnt;
int p[501], chk[501];

int findParent(int x) {
	if (p[x] == x) return x;
	else return p[x] = findParent(p[x]);
}

void init() {
	cnt = 0;
	memset(chk, 0, sizeof(chk));
	for (int i = 1; i <= n; i++) p[i] = i;
}

int main() {
	for (int idx = 1; scanf("%d %d", &n, &m) && n; idx++) {
		init();
		while (m-- && scanf("%d %d", &a, &b)) {
			int pa = findParent(a);
			int pb = findParent(b);
			if (pa != pb) {
				if (chk[pa] == -INF || chk[pb] == -INF) {
                    // 기존의 부모가 사이클이 있는 그룹였으면
                    // 새로운 노드도 트리가 되지 못하는 그룹에 속함
					chk[pa] = chk[pb] = -INF;
				}
				p[pa] = pb;
			}
			else chk[pa] = -INF; // 이미 같은 그룹이면 사이클 발생
		}
		for (int i = 1; i <= n; i++) chk[findParent(i)]++; // 그룹 중복 제거
		for (int i = 1; i <= n; i++)
			if (chk[i] > 0) cnt++; // 사이클 있는 그룹은 -INF이므로, 양수가 되지 못함
		printf("Case %d: ", idx);
		if (cnt == 0) printf("No trees.\n");
		else if (cnt == 1) printf("There is one tree.\n");
		else printf("A forest of %d trees.\n", cnt);
	}
}
반응형

'Algorithm' 카테고리의 다른 글

백준 2470 : 두 용액  (0) 2021.11.16
백준 2096 : 내려가기  (0) 2021.11.16
백준 2887 : 행성 터널  (0) 2021.11.16
백준 4386 : 별자리 만들기  (0) 2021.11.16
백준 14225 : 부분수열의 합  (0) 2021.11.16

+ Recent posts