Skip to main content
  1. Posts/
  2. Algorithm/

BOJ 5925 Cow Beauty Pageant

·435 words·3 mins
Jiho Kim
Author
Jiho Kim
달려 또 달려

📝 문제 정보
#

🧐 관찰 및 접근
#

  • X로 그려지는 영역이 3개가 있고, 최소한의 비용으로 이들을 연결해야한다.
    • 멀티 소스 BFS와 같은 맛으로 가능할 것 같다. 3개니까 전수조사 해도 되겠지.
  • 아, 근데 좀 사고인 경우가 있구나.
.....
..X..
.X.X.
.....
  • 위와 같은 경우에, 하나만으로도 칠할 수 있는 것 같다.
    • 위와 같은 경우에, 세 그룹이 한 정점에서 무조건 모이게 된다.
    • 따라서 빈 정점을 잡고, 거기서 세 그룹까지의 최단경로를 이용하자.

💻 풀이
#

  • 코드 (C++):

void solve(){
    int N, M; cin >> N >> M;
    vector<string> S(N);
    rep(i, 0, N) cin >> S[i];

    vector<vector<int>> board(N, vector<int>(M));
    int color = 0;
    rep(i, 0, N) rep(j, 0, M) {
        if(S[i][j] == 'X' && board[i][j] == 0){
            queue<pii> Q;
            Q.push({i, j});
            board[i][j] = ++color;
            while(!Q.empty()){
                auto [cx, cy] = Q.front(); Q.pop();
                rep(d, 0, 4){
                    int nx = cx + dx[d];
                    int ny = cy + dy[d];
                    if(nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
                    if(S[nx][ny] == 'X' && board[nx][ny] == 0){
                        board[nx][ny] = color;
                        Q.push({nx, ny});
                    }
                }
            }
        }
    }

    vector<ll> dists;
    auto getDist = [&](int c1, int c2) -> ll {
        vector<vector<int>> dist(N, vector<int>(M, -1));
        queue<pii> Q;
        rep(i, 0, N) rep(j, 0, M){
            if(board[i][j] == c1){
                dist[i][j] = 0;
                Q.push({i, j});
            }
        }
        while(!Q.empty()){
            auto [cx, cy] = Q.front(); Q.pop();
            rep(d, 0, 4){
                int nx = cx + dx[d];
                int ny = cy + dy[d];
                if(nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
                if(board[nx][ny] == c2){
                    return dist[cx][cy];
                }
                if(board[nx][ny] == 0 && dist[nx][ny] == -1){
                    dist[nx][ny] = dist[cx][cy] + 1;
                    Q.push({nx, ny});
                }
            }
        }
        return (ll)1e18;
    };

    rep(i, 1, 4) rep(j, i+1, 4) dists.push_back(getDist(i, j));
    sort(all(dists));

    ll ans = dists[0] + dists[1];

    auto getDist2 = [&](int cx, int cy, int c) -> ll {
        vector<vector<int>> dist(N, vector<int>(M, -1));
        queue<pii> Q;
        dist[cx][cy] = 0;
        Q.push({cx, cy});
        while(!Q.empty()){
            auto [x, y] = Q.front(); Q.pop();
            rep(d, 0, 4){
                int nx = x + dx[d];
                int ny = y + dy[d];
                if(nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
                if(board[nx][ny] == c){
                    return dist[x][y];
                }
                if(board[nx][ny] == 0 && dist[nx][ny] == -1){
                    dist[nx][ny] = dist[x][y] + 1;
                    Q.push({nx, ny});
                }
            }
        }
        return (ll)1e18;
    };
    rep(i, 0, N) rep(j, 0, M) if(board[i][j] == 0){
        ans = min(ans, getDist2(i, j, 1) + getDist2(i, j, 2) + getDist2(i, j, 3) + 1);
    }

    cout << ans << "\n";
}
🔒

구현 코드 잠금

아래 쿠팡 링크를 방문하시면 코드가 공개됩니다.
광고 수익이 블로그 운영에 도움이 됩니다 🙏

🛒 쿠팡 방문하고 코드 보기

방문 후 잠금이 자동으로 해제됩니다