티스토리 뷰
https://www.acmicpc.net/problem/1761
트리에서의 두 정점 사이의 경로는 하나만 존재하므로 경로 사이의 거리가 곧 최단 거리가 된다. 이 점을 이용하여 루트에서 부터의 정점 i까지의 거리를 d[i]라 하면 두 정점 u,v 사이의 거리는 d[u]+d[v]에서 경로에 해당되지 않는 부분인 d[lca(u,v)]가 두 번 포함되었으므로 dist(u,v)=d[u]+d[v]-2*d[lca(u,v)] 이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #include <cstdio> #include <vector> #include <queue> #include <algorithm> using namespace std; int d[40001],p[40001],l[40001],c[40001]; vector<pair<int,int>> a[40001]; void bfs() { d[1]=p[1]=l[1]=0,c[1]=true; queue<int> q; q.push(1); while(!q.empty()) { int now=q.front(); q.pop(); for(auto i : a[now]) { int next=i.first,cost=i.second; if(c[next]) continue; c[next]=true; d[next]=d[now]+cost; p[next]=now; l[next]=l[now]+1; q.push(next); } } } int lca(int u,int v) { if(l[u]<l[v]) swap(u,v); while(l[u]!=l[v]) u=p[u]; while(u!=v) u=p[u],v=p[v]; return u; } int main() { int n,m,u,v,c; scanf("%d",&n); while(--n) { scanf("%d %d %d",&u,&v,&c); a[u].push_back({v,c}); a[v].push_back({u,c}); } bfs(); scanf("%d",&m); while(m--) { scanf("%d %d",&u,&v); printf("%d\n",d[u]+d[v]-2*d[lca(u,v)]); } return 0; } | cs |
'Algorithm > BOJ' 카테고리의 다른 글
9657 돌 게임 3 (0) | 2018.02.14 |
---|---|
10775 공항 (0) | 2018.02.14 |
11437 LCA (0) | 2018.02.12 |
1915 가장 큰 정사각형 (0) | 2018.02.12 |
4150 피보나치 수 (0) | 2018.02.12 |