[백준]/C++

백준 21738번 얼음깨기 펭귄 [C++]

경우42 2025. 1. 15. 14:21
반응형

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

 

 

#문제 간단 정리

 

bfs 문제

 

#문제 해결 방법

 

우선 문제를 잘 이해해 보면

펭귄이 이어진 지지대가 2개 는 있어야 된다 

-> 즉 펭귄과 지지대를 잇는 경로만 멀쩡히 있으면 된다

-> 즉 가장 가까운 지지대 2개를 골라서 그 지지대 경로를 제외한 모든 얼음을 깨면 된다

-> 가장 가까운 지지대 2개를 bfs 를 이용해서 찾는다

 

라는 발상이 가능하다

중요한건 dfs 를 처음에 사용하려 했는데 가장 가까운 지지대 경로 를 찾아야해서 

부적합 하기 때문에 bfs 를 사용했고 ,( 재귀형식으로 만드는ㄴ게 불가능하진 않겠지만 귀찮을 것이다)

 

그리고 결국 가장 가까운 거리의 2개의 지지대 경로만 찾으면 되기 때문에

2개를 찾자마자 바로 결과를 출력했다.

딱히 거리만 같으면 되니까 더 탐색할 이유가 없다.

 

 

 

 

#전체 코드

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, s, p;
    cin >> n >> s >> p;

    // 인접 리스트 준비
    vector<vector<int>> graph(n + 1);
    vector<bool> visited(n + 1, false);

    // 간선 입력 (트리 구조)
    for (int i = 1; i < n; i++) {
        int a, b;
        cin >> a >> b;
        graph[a].push_back(b);
        graph[b].push_back(a);
    }

    // BFS 준비
    queue<pair<int, int>> q;
    q.push({ p, 0 });
    visited[p] = true;

    bool find = false;
    int ans = 0;

    while (!q.empty()) {
        // queue에서 (현재 노드, 거리) 꺼내기
        int now = q.front().first;
        int dist = q.front().second;
        q.pop();

        // 현재 노드에 인접한 노드 탐색
        for (auto next : graph[now]) {
            // 아직 방문하지 않은 경우만
            if (!visited[next]) {
                visited[next] = true;

                // 지지대 노드(번호 <= s) 발견 시 처리
                if (next <= s) {
                    // ans가 0이면 첫 번째 지지대,
                    // 그 뒤면 두 번째 지지대라는 가정으로 ans 계산
                    if (find == false) {
                        ans -= (dist + 1);
                        find = true;
                    }
                    else {
                        ans -= (dist + 1);
                        cout << n + ans - 1 << endl;
                        return 0;
                    }
                }
                else {
                    // 일반 노드는 계속 큐에 넣어서 탐색
                    q.push({ next, dist + 1 });
                }
            }
        }
    }




    return 0;
}
반응형