본문 바로가기
Develog/코딩테스트

UnionFind(합집합 찾기) 알고리즘

by 예 강 2024. 10. 12.

 

class UnionFind{
	constructor(size){
    	this.parent = Array.from({length:size}, (_, i)=>i)
    }

	find(x){
    	if(this.parent[x] === x){
        	return x;
        }
        return (this.parent[x] = this.find(this.parent[x]));   //부모의 값을 넣음으로써 경로 단축
    }
  
 	union(x, y){
    	const rootX = this.find(x);
        const rootY = this.find(y);
        if (rootX !== rootY){
        	this.parent[rootX] = rootY;
        }
    }
}

 

 

< 기본 로직 >

union으로 연결하고 싶은 노드들을 연결 한뒤 나중에 찾을땐 find 함수로 연결 되어 있는지 (합집합 인지) 검사한다.

 

union 함수

연결하고자 하는 두 x, y의 원소가 서로 다르면 rootY(오른쪽값)으로 설정한다.

 

Find 함수

 

return (this.parent[x] = this.find(this.parent[x]));   

 

//위 부분이 핵심인데, 최초에 탐색할 때 부모의 값으로 해당 키값을 갱신한다.
이러면 다음부턴 탐색할 땐 경로를 단축하게 해준다.

 

https://www.acmicpc.net/problem/1976

해당문제에 사용했으며 전체적인 코드는 아래와 같다

 

const inputFile = process.platform === "linux" ? "/dev/stdin" : "./example.txt";
const input = require("fs")
    .readFileSync(inputFile)
    .toString()
    .trim()
    .split("\n");

let index = 0;
let cities = Number(input[index++].trim());
let count = Number(input[index++].trim());

class UnionFind {
    constructor(size) {
        this.parent = Array.from({ length: size }, (_, i) => i);
    }

    find(x) {
        if (this.parent[x] === x) {
            return x;
        }
        return (this.parent[x] = this.find(this.parent[x]));
    }

    union(x, y) {
        const rootX = this.find(x);
        const rootY = this.find(y);
        if (rootX !== rootY) {
            this.parent[rootX] = rootY;
        }
    }
}

const map = [];

for (let i = 0; i < count; i++) {
    map.push(input[index++].trim().split(" ").map(Number));
}

const plan = input[index].trim().split(" ").map(Number);

const uf = new UnionFind(cities);

for (let i = 0; i < cities; i++) {
    for (let j = 0; j < cities; j++) {
        if (map[i][j] === 1) uf.union(i, j);
    }
}

function isPlanValid(plan) {
    const start = plan[0] - 1;
    for (let i = 1; i < plan.length; i++) {
        const nextCity = plan[i] - 1;
        if (uf.find(start) !== uf.find(nextCity)) return false;
    }
    return true;
}

console.log(isPlanValid(plan) ? "YES" : "NO");

'Develog > 코딩테스트' 카테고리의 다른 글

자주쓰는 문법 모음  (0) 2022.06.25
파이썬 자주쓰는 함수 모음  (0) 2022.06.14
[python]sys.stdin  (0) 2022.06.13
코딩테스트 기초쌓기  (0) 2022.03.20