[ 백준 ] 1976 / 여행 가자

金弘均·2021년 9월 15일
0

Baekjoon Online Judge

목록 보기
33/228
post-thumbnail

# Appreciation

/*
 * Problem :: 1976 / 여행 가자
 *
 * Kind :: Union Find
 *
 * Insight
 * - 여행 중, 어느 도시를 중복해서 많이 들리는 것은 상관없다
 *   여행경로안의 도시들끼리 서로 연결되어 있기만 하면 된다
 *   + 연결... 서로 중복되지 않음...
 *     각 도시들을 원소로 생각하면...
 *     # Disjoint Set!!!
 *       Union Find!!!
 */

# Code

//
//  BOJ
//  ver.C++
//
//  Created by GGlifer
//
//  Open Source

#include <iostream>
#include <algorithm>

using namespace std;

#define endl '\n'

// Set up : Global Variables
int P[200+1], R[200+1];

// Set up : Functions Declaration
int find(int x);
void merge(int x, int y);


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    int N; cin >> N;
    int M; cin >> M;
    for (int i=1; i<=N; i++) { P[i] = i, R[i] = 1; }
    for (int i=1; i<=N; i++) {
        for (int j=1; j<=N; j++) {
            bool isConn; cin >> isConn;

            // Process
            if (isConn) { /* 도시 i 와 j 가 연결되어있다면 */
                /* 도시 i 가 속한 집합과 도시 j 가 속한 집합을 합침 */
                if (find(i) != find(j)) {
                    merge(i, j);
                }
            }
        }
    }

    // Set up: Input
    int C[M];
    for (int i=0; i<M; i++)
        cin >> C[i];

    // Process
    bool isPossible = true;
    for (int i=0; i<M-1; i++) {
        /* 여행경로에서 인접한 도시들간의 집합이 서로 다르다면 */
        if (find(C[i]) != find(C[i+1])) {
            isPossible = false; /* 여행 불가 */
            break;
        }
    }

    // Control : Output
    cout << ((isPossible) ? "YES" : "NO") << endl;
}

// Helper Functions
int find(int x)
/* 도시 x 의 대표도시를 반환하는 함수 */
{
    if (P[x] == x) return x;
    return P[x] = find(P[x]);
}

void merge(int x, int y)
/* 도시 x 가 속한 집합과 도시 y 가 속한 집합을 합치는 함수 */
{
    x = find(x), y = find(y);
    if (x == y) return;

    if (R[x] < R[y]) swap(x, y);
    P[y] = x;
    if (R[x] == R[y]) R[x]++;
}
profile
이런 미친 게임을 봤나! - 옥냥이

0개의 댓글