문제 URL : https://www.acmicpc.net/problem/8012
8012번: 한동이는 영업사원!
한동이는 경상도내를 돌아다니면서 열심히 일하는 영업사원이다. 예전에는 자기가 원하는 도시만 골라서 다닐 수 있었지만 시대가 바뀌어서 이제 그렇게는 하지 못하게 되었다. 시대가 바뀜에
www.acmicpc.net
문제 접근법 :
두노드간의 거리문제입니다. 빠르게 구하기위해
LCA의 depth를 이용하면되는데
두정점을 a,b라 할때
depth[a]+depth[b]-2*depth[lca(a,b)] 를 통해 쉽게 구할수있습니다.
소스코드 :
//By 콩순이냉장고
#include <bits/stdc++.h>
using namespace std;
vector<int> v[30001],depth,iv;
int n, m;
int parent[17][30001];
void input(){
cin>>n;
int a,b;
for(int i=0;i<n-1;i++){
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
cin>>m;
iv.resize(m);
for(int i=0;i<m;i++)cin>>iv[i];
}
void dfs(int cur=1,int p=0,int h=0){
parent[0][cur]=p;
depth[cur]=h;
for(int next:v[cur]){
if(depth[next]==-1)dfs(next,cur,h+1);
}
}
void sparseTable(){
for(int i=1;i<=16;i++){
for(int j=1;j<=n;j++){
parent[i][j]=parent[i-1][parent[i-1][j]];
}
}
}
int lca(int x,int y){
if(depth[x]>depth[y])swap(x,y);
for(int i=16;i>=0;i--){
if(depth[y]-depth[x]>=(1<<i)){
y=parent[i][y];
}
}
if(x==y)return x;
for(int i=16;i>=0;i--){
if(parent[i][x]!=parent[i][y]){
x=parent[i][x];
y=parent[i][y];
}
}
return parent[0][x];
}
void solve(){
depth=vector<int>(n+1,-1);
dfs();
sparseTable();
long long sum=0;
for(int i=1;i<m;i++){
sum+=depth[iv[i]]+depth[iv[i-1]]-(2*depth[lca(iv[i],iv[i-1])]);
}
cout<<sum<<"\n";
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
//freopen("input.txt", "r", stdin);
input();
solve();
}
궁금한점 혹은 모르는점 어떤질문이든 댓글은 언제나 환영입니다.
'백준' 카테고리의 다른 글
백준 2610 회의준비 (0) | 2023.01.18 |
---|---|
백준 2617 구슬 찾기 (0) | 2023.01.18 |
백준 15480 LCA와 쿼리 (0) | 2023.01.18 |
백준 14676 영우는 사기꾼? (0) | 2022.11.15 |
백준 5525 IOIOI (0) | 2022.11.01 |