[BOJ] 17472๋ฒˆ | ๋‹ค๋ฆฌ ๋งŒ๋“ค๊ธฐ 2 (C++)

2023. 12. 12. 19:45ใ†Coding Test/BOJ

๐Ÿ”—๋ฌธ์ œ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ
 

17472๋ฒˆ: ๋‹ค๋ฆฌ ๋งŒ๋“ค๊ธฐ 2

์ฒซ์งธ ์ค„์— ์ง€๋„์˜ ์„ธ๋กœ ํฌ๊ธฐ N๊ณผ ๊ฐ€๋กœ ํฌ๊ธฐ M์ด ์ฃผ์–ด์ง„๋‹ค. ๋‘˜์งธ ์ค„๋ถ€ํ„ฐ N๊ฐœ์˜ ์ค„์— ์ง€๋„์˜ ์ •๋ณด๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ๊ฐ ์ค„์€ M๊ฐœ์˜ ์ˆ˜๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์œผ๋ฉฐ, ์ˆ˜๋Š” 0 ๋˜๋Š” 1์ด๋‹ค. 0์€ ๋ฐ”๋‹ค, 1์€ ๋•…์„ ์˜๋ฏธํ•œ๋‹ค.

www.acmicpc.net

 

๐Ÿ‘จ‍๐Ÿ’ปํ’€์ด ๊ณผ์ •

 

BFS + DFS + ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ(MST) ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•ด์•ผ ํ’€ ์ˆ˜ ์žˆ๋Š”, ๋Œ€๋‹จํžˆ ์ฒด๋ ฅ์ ์œผ๋กœ ํž˜๋“  ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ ๋ฌธ์ œ์—์„œ ์ฃผ์–ด์ง„ ์กฐ๊ฑด๋“ค์ด ๊นŒ๋‹ค๋กญ์ง„ ์•Š์•„, ๊ตฌํ˜„๋งŒ ์ œ๋Œ€๋กœ ํ•œ๋‹ค๋ฉด ํ†ต๊ณผ๋Š” ์‰ฝ๊ฒŒ ๋˜๋„ค์š”. ์ œ๊ฐ€ ํ‘ผ ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

  1. ์ฃผ์–ด์ง„ ์ž…๋ ฅ์„ 2์ฐจ์› ๋ฐฐ์—ด์— ์ €์žฅํ•˜๋˜, ๋•…(1)์€ 1์ด ์•„๋‹ˆ๋ผ ์—„์ฒญ ํฐ ๋‹ค๋ฅธ ์ˆซ์ž(1์–ต)๋กœ ๋Œ€์‹  ์ฑ„์›Œ์ค๋‹ˆ๋‹ค.
  2. BFS ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ†ตํ•ด, ๊ฐ ์„ฌ์˜ ๋ฒˆํ˜ธ๋ฅผ ํ•ด๋‹น ์„ฌ์˜ ์˜์—ญ์— ์ฑ„์›Œ์ค๋‹ˆ๋‹ค.
  3. DFS ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ†ตํ•ด, ์„œ๋กœ ๋‹ค๋ฅธ ๋ฒˆํ˜ธ์˜ ์„ฌ ๋ผ๋ฆฌ์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๋ณ„๋„์˜ ๋ฐฐ์—ด(distances)์— ์ €์žฅํ•ด์ค๋‹ˆ๋‹ค.
    • distances[i][j] ๋Š” i๋ฒˆ ์„ฌ์—์„œ j๋ฒˆ ์„ฌ์œผ๋กœ ๊ฐ€๋Š” ๊ฑฐ๋ฆฌ์ด๋ฉฐ, ์ดˆ๊ธฐ๊ฐ’์€ ๋งค์šฐ ํฐ ์ˆซ์ž(1์–ต)์œผ๋กœ ์ €์žฅ
    • ๊ฑฐ๋ฆฌ๊ฐ€ 1 ์ดํ•˜์ด๊ฑฐ๋‚˜, ๋‹ค๋ฆฌ๋ฅผ ๊บพ์–ด์„œ ์ง€์–ด์•ผ ์—ฐ๊ฒฐ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ์—๋Š” ๊ฑด๋„ˆ๋›ฐ๊ธฐ
    • ์ด๋ฏธ ๊ฐ’์ด ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” ์ƒˆ ๊ฐ’๊ณผ ๋น„๊ตํ•˜์—ฌ ๋” ์ž‘์€ ๊ฐ’์œผ๋กœ ๊ฐฑ์‹ 
  4. ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•ด, ๊ฐ ์„ฌ์„ ์ž‡๋Š” ์ตœ์†Ÿ๊ฐ’์„ ๊ตฌํ•ด์„œ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
    • ์ €๋Š” ํ”„๋ฆผ์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜(Prim's Algorithm)์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์œ„์ฒ˜๋Ÿผ ๊ณผ์ •์€ ํฌ๊ฒŒ 4๊ฐ€์ง€์ธ๋ฐ, ๊ฐ ๊ณผ์ •์„ ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์ค‘๊ฐ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด ๋ฌธ์ œ๊ฐ€ ์—†๋Š”์ง€ ์ ๊ฒ€ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ตฌํ˜„ ๋ฌธ์ œ๋Š” ์ด๋ ‡๊ฒŒ ์ง„ํ–‰ํ•ด์•ผ, ์‹œ๊ฐ„์„ ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋”๋ผ๊ตฌ์š”.

 

โœ๏ธ์†Œ์Šค ์ฝ”๋“œ ๋ฐ ๊ฒฐ๊ณผ

#include <iostream>
#include <vector>
#include <queue>

using namespace std;
#define FAST_IO ios::sync_with_stdio(false); cout.tie(NULL); cin.tie(NULL);

using Position = pair<int, int>;    // <ํ–‰, ์—ด>
using Data = pair<int, int>;        // <๊ฑฐ๋ฆฌ, ์„ฌ ๋ฒˆํ˜ธ>

vector<vector<int>> Directions { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };  // ์ƒํ•˜์ขŒ์šฐ

const int SEA = 0;
const int MAX = 100000000;
int N, M;


void Input(vector<vector<int>>& field);
void SetIsland(vector<vector<int>>& field, int& islandNumber);
void BFS(vector<vector<int>>& field, const int islandNumber, int row, int col);
void GetIslandDistances(const vector<vector<int>>& field, vector<vector<int>>& distances);
void DFS(const vector<vector<int>>& field, vector<vector<int>>& distances, const vector<int>& direction, int islandNumber, int row, int col, int distance);
int Prim(const vector<vector<int>>& distances, int start);

int main() {
    FAST_IO
    cin >> N >> M;

    int islandNumber = 1;
    vector<vector<int>> field(N, vector<int>(M));
    
    Input(field);
    SetIsland(field, islandNumber);

    vector<vector<int>> distances(islandNumber, vector<int>(islandNumber, MAX));
    GetIslandDistances(field, distances);

    int answer = Prim(distances, 1);
    cout << answer;
    return 0;
}

int Prim(const vector<vector<int>>& distances, int start) {
    vector<bool> MST(distances.size(), false);
    MST[start] = true;

    priority_queue<Data, vector<Data>, greater<Data>> edges;
    for (int i = 1; i < distances[start].size(); i++) {
        if (i == start or distances[start][i] == MAX)
            continue;
        edges.emplace(distances[start][i], i);
    }

    int answer = 0;
    while (!edges.empty()) {
        int distance = edges.top().first;
        int islandNumber = edges.top().second;
        edges.pop();

        if (MST[islandNumber])
            continue;
        
        MST[islandNumber] = true;
        answer += distance;

        for (int i = 1; i < distances[islandNumber].size(); i++) {
            if (i == islandNumber or MST[i] or distances[islandNumber][i] == MAX)
                continue;
            edges.emplace(distances[islandNumber][i], i);
        }
    }

    for (int i = 1; i < MST.size(); i++)
        if (!MST[i])
            return -1;
    return answer;
}


void DFS(const vector<vector<int>>& field, vector<vector<int>>& distances, const vector<int>& direction, int islandNumber, int row, int col, int distance) {
    int nextRow = row + direction[0];
    int nextCol = col + direction[1];

    if (nextRow < 0 or nextRow >= N or nextCol < 0 or nextCol >= M)
        return;
    if (field[nextRow][nextCol] == islandNumber)
        return;
    if (field[nextRow][nextCol] == SEA) {
        DFS(field, distances, direction, islandNumber, nextRow, nextCol, distance + 1);
        return;
    }

    if (distance <= 1)
        return;

    int otherIslandNumber = field[nextRow][nextCol];
    int newDistance = min(distance, distances[islandNumber][otherIslandNumber]);

    distances[islandNumber][otherIslandNumber] = newDistance;
    distances[otherIslandNumber][islandNumber] = newDistance;
}

void GetIslandDistances(const vector<vector<int>>& field, vector<vector<int>>& distances) {
    for (int row = 0; row < N; row++) {
        for (int col = 0; col < M; col++) {
            if (field[row][col] == SEA)
                continue;
            
            for (const auto& direction : Directions)
                DFS(field, distances, direction, field[row][col], row, col, 0);
        }
    }
}

void Input(vector<vector<int>>& field) {
    for (int row = 0; row < N; row++)
        for (int col = 0; col < M; col++) {
            int value;
            cin >> value;

            value = (value == 1) ? MAX : value;
            field[row][col] = value;
        }
}

void SetIsland(vector<vector<int>>& field, int& islandNumber) {
    for (int row = 0; row < N; row++) {
        for (int col = 0; col < M; col++) {
            if (field[row][col] == SEA or field[row][col] < islandNumber)
                continue;
            BFS(field, islandNumber++, row, col);
        }
    }
}

void BFS(vector<vector<int>>& field, const int islandNumber, int row, int col) {
    queue<Position> positions;
    positions.emplace(row, col);
    field[row][col] = islandNumber;

    while (!positions.empty()) {
        int currentRow = positions.front().first;
        int currentCol = positions.front().second;
        positions.pop();

        for (const auto& direction : Directions) {
            int nextRow = currentRow + direction[0];
            int nextCol = currentCol + direction[1];

            if (nextRow < 0 or nextRow >= N or nextCol < 0 or nextCol >= M)
                continue;
            if (field[nextRow][nextCol] == SEA or field[nextRow][nextCol] == islandNumber)
                continue;
            
            field[nextRow][nextCol] = islandNumber;
            positions.emplace(nextRow, nextCol);
        }
    }
}

 

 

728x90
๋ฐ˜์‘ํ˜•