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

BOJ 1761 정점들의 거리

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

📝 문제 정보
#

🧐 관찰 및 접근
#

  • 트리에서, 두 정점 사이의 경로는 유일하다.
    • 해당 경로는 두 정점의 LCA를 지난다.
    • 두 점 사이의 거리는 $d(u) + d(v) - 2*d(\text{LCA}(u, v))$로 계산할 수 있다.

💻 풀이
#

  • 코드 (C++):

void dfs(int cur, int _par){
    for(auto [nxt, w]: links[cur]){
        if(nxt == _par) continue;
        dist[nxt] = dist[cur] + w;
        depth[nxt] = depth[cur] + 1;
        par[nxt][0] = cur;
        dfs(nxt, cur);
    }
}

int LCA(int u, int v){
    if(u == v) return u;
    if(depth[u] < depth[v]) swap(u, v);
    int diff = depth[u] - depth[v];
    rep(i, 0, 16) if((diff >> i) & 1) u = par[u][i];
    if(u == v) return u;
    rrep(i, 16, 0){
        if(par[u][i] != par[v][i]){
            u = par[u][i];
            v = par[v][i];
        }
    }
    return par[u][0];
}

ll getDist(int u, int v){
    int lca = LCA(u, v);
    return dist[u] + dist[v] - 2 * dist[lca];
}

void solve(){
    cin >> N;
    rep(i, 0, N-1){
        int u, v, w; cin >> u >> v >> w;
        links[u].push_back({v, w});
        links[v].push_back({u, w});
    }

    dfs(1, -1);
    rep(j, 1, 16) rep(i, 1, N+1) par[i][j] = par[par[i][j-1]][j-1];
    cin >> Q;
    while(Q--){
        int u, v; cin >> u >> v;
        cout << getDist(u, v) << '\n';
    }
}
🔒

구현 코드 잠금

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

🛒 쿠팡 방문하고 코드 보기

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