본문 바로가기

Algorithm/BAEKJOON

[BOJ] 1761번 정점들의 거리 (C++)

728x90
반응형

https://www.acmicpc.net/problem/1761

 

1761번: 정점들의 거리

첫째 줄에 노드의 개수 N이 입력되고 다음 N-1개의 줄에 트리 상에 연결된 두 점과 거리를 입력받는다. 그 다음 줄에 M이 주어지고, 다음 M개의 줄에 거리를 알고 싶은 노드 쌍이 한 줄에 한 쌍씩

www.acmicpc.net

 

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
 
int parent[40001];
int depth[40001];
int length[40001];
bool visited[40001];
 
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
 
	int n;
	cin >> n;
	vector<pair<int, int>> node[40001];
	for(int i = 0; i < n - 1; i++){
		int x, y, dis;
		cin >> x >> y >> dis;
		node[x].push_back({y, dis});
		node[y].push_back({x, dis});
	}
 
	queue<int> q;
	q.push(1);
	visited[1] = true;
	while(!q.empty()){
		int cur = q.front();
		q.pop();
		for(int i = 0; i < node[cur].size(); i++){
			int next = node[cur][i].first;
			int len = node[cur][i].second;
			if(!visited[next]){
				depth[next] = depth[cur] + 1;
				parent[next] = cur;
				length[next] = length[cur] + len;
				visited[next] = true;
				q.push(next);
			}
		}
	}
 
	int m;
	cin >> m;
	for(int i = 0; i < m; i++){
		int x, y;
		cin >> x >> y;
		int a = length[x];
		int b = length[y];
		if(depth[x] > depth[y]){
			int tmp = x;
			x = y;
			y = tmp;
		}
		while(depth[x] != depth[y]){
			y = parent[y];
		}
		while(x != y){
			x = parent[x];
			y = parent[y];
		}
		cout << a + b - 2 * length[x] << '\n';
	}
	return 0;
}

루트에서 정점 i까지의 거리를 length[i]라 하면 두 정점 u,v 사이의 거리는 length[u]+length[v]에서 경로에 해당되지 않는 부분인 length[lca(u,v)]가 두 번 포함되었으므로 length[u]+length[v]-2*length[lca(u,v)] 이다.

728x90
반응형