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

BOJ 33527 신촌 길찾기 서비스

·277 words·2 mins
Jiho Kim
Author
Jiho Kim
달려 또 달려

📝 문제 정보
#

🧐 관찰 및 접근
#

  • 뭔가 전반적으로 세팅이 BOJ 5214 환승이 생각나는 것 같기도?
    • 나이브하게 돈다면, 각 노선에 있을 수 있는 최대 정류장 수가 10만개니까, 이걸 다 돌기 시작하면 상당히 막막해진다.
  • 그림을 그려서 어떤 상황인지 더 잘 판단해보자.
    • ![[Drawing 2026-02-17 14.06.51.excalidraw.png]]
      • 일단 예제 1번은 이런데, 흠. 확실히 정류장보단 노선 단위로 어떻게 잘 보고싶긴 하다.
  • 노선은 총 $5 \times X = 500$개이다.
    • 이때, 노선의 환승 각 정류장 $N$개마다 $\binom{5}{2}$ 개이므로 최대 $100\,000 \times = 1\,000\,000$개인 것 같다. 중복도 제거할수도 있고.
    • 아? 이게 노선이 충분히 적으니, 플로이드 워셜이 가능해보인다.
  • 쿼리는 정점에 대해 들어오니, $U_i, V_i$가 각각 5개 노선에 속하는 경우 25가지에 대해 노선으로 계산하면 될 것 같다.

💻 풀이
#

  • 코드 (C++):
void solve(){
    int N, X; cin >> N >> X;
    vector<array<int, 5>> bus(N);
    rep(i, 0, N) rep(j, 0, 5) cin >> bus[i][j];

    auto toIdx = [&](pii p){ 
        return p.first*X + (p.second - 1);
    };

    vector<vector<int>> dist(5*X, vector<int>(5*X, 1e9));
    rep(i, 0, 5*X) dist[i][i] = 0;
    rep(i, 0, N) rep(j, 0, 5) rep(k, j+1, 5){
        int u = toIdx({j, bus[i][j]}), v = toIdx({k, bus[i][k]});
        dist[u][v] = dist[v][u] = 1;
    }
    rep(k, 0, 5*X) rep(i, 0, 5*X) rep(j, 0, 5*X) dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);

    int Q; cin >> Q;
    while(Q--){
        int u, v; cin >> u >> v;
        int ans = 1e9;
        rep(i, 0, 5) rep(j, 0, 5){
            int idx_u = toIdx({i, bus[u-1][i]}), idx_v = toIdx({j, bus[v-1][j]});
            ans = min(ans, dist[idx_u][idx_v]);
        }
        cout << (ans == 1e9 ? -1 : ans+1) << "\n";
    }
}
🔒

구현 코드 잠금

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

🛒 쿠팡 방문하고 코드 보기

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