백준 3176 도로 네트워크
https://www.acmicpc.net/problem/3176
LCA를 구하는 과정과 매우 유사하기 때문에, LCA를 모르시는 분이라면 LCA 를 보고 오시는 것을 추천드립니다.
LCA를 구하는 과정에서 부모 노드를 저장하는 table처럼 최소 거리와 최대 거리를 저장하는 parse table도 각각 하나씩 만들어 줍니다.
최소 거리를 저장하는 점화식은 min_dst[i][j]=min(min_dst[i-1][j],min_dst[i-1][par[i-1][j]])입니다. (최대 거리는 동일하니 굳이 한 번 더 하진 않겠습니다.)
#include<bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
const int SZ=100005;
const int MXH=18;
typedef pair<int,int> pii;
vector<pii> graph[SZ];
int par[MXH][SZ];
int min_dst[MXH][SZ];
int max_dst[MXH][SZ];
int level[SZ];
int n;
int dfs(int x, int p, int w, int lv){
min_dst[0][x]=w;
max_dst[0][x]=w;
par[0][x]=p;
level[x]=lv;
for(auto nxt:graph[x]){
if(nxt.ff==p) continue;
dfs(nxt.ff,x,nxt.ss,lv+1);
}
}
int memo(){
for(int i=1;i<MXH;i++){
for(int j=1;j<=n;j++){
par[i][j]=par[i-1][par[i-1][j]];
min_dst[i][j]=min(min_dst[i-1][j],min_dst[i-1][par[i-1][j]]);
max_dst[i][j]=max(max_dst[i-1][j],max_dst[i-1][par[i-1][j]]);
}
}
}
int min_query(int x, int y){
int ans=INT_MAX;
// minimum weight during level up
int xy=level[x]-level[y];
for(int i=MXH-1;i>=0;i--){
if(xy>0 && (1<<i)&xy){
ans=min(ans,min_dst[i][x]);
x=par[i][x];
}
if(xy<0 && (1<<i)&(-xy)){
ans=min(ans,min_dst[i][y]);
y=par[i][y];
}
}
if(x==y) return ans;
// minimum weight during jump
for(int i=MXH-1;i>=0;i--){
if(par[i][x]!=par[i][y]){
ans=min(ans,min(min_dst[i][x],min_dst[i][y]));
x=par[i][x];
y=par[i][y];
}
}
return ans=min(ans,min(min_dst[0][x],min_dst[0][y]));
}
int max_query(int x, int y){
int ans=0;
// maximum weight during level up
int xy=level[x]-level[y];
for(int i=MXH-1;i>=0;i--){
if(xy>0 && (1<<i)&xy){
ans=max(ans,max_dst[i][x]);
x=par[i][x];
}
if(xy<0 && (1<<i)&(-xy)){
ans=max(ans,max_dst[i][y]);
y=par[i][y];
}
}
if(x==y) return ans;
// maximum weight during jump
for(int i=MXH-1;i>=0;i--){
if(par[i][x]!=par[i][y]){
ans=max(ans,max(max_dst[i][x],max_dst[i][y]));
x=par[i][x];
y=par[i][y];
}
}
return ans=max(ans,max(max_dst[0][x],max_dst[0][y]));
}
int main(void){
ios::sync_with_stdio(false); cin.tie(NULL);
cin>>n;
for(int i=1;i<n;i++){
int x,y,z; cin>>x>>y>>z;
graph[x].push_back({y,z});
graph[y].push_back({x,z});
}
dfs(1,0,0,0);
memo();
int q; cin>>q;
while(q--){
int x,y; cin>>x>>y;
cout<<min_query(x,y)<<" "<<max_query(x,y)<<'\n';
}
return 0;
}