240911 LCA 2

Jongleee·2024년 9월 11일
0

TIL

목록 보기
675/737
static int n;
static List<Integer>[] adj;
static int[] depth;
static int[][] dp;
static int maxLog;

@SuppressWarnings("unchecked")
public static void main(String[] args) throws IOException {
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
	StringBuilder result = new StringBuilder();

	n = Integer.parseInt(br.readLine());

	adj = new ArrayList[n + 1];
	for (int i = 1; i <= n; i++) {
		adj[i] = new ArrayList<>();
	}

	for (int i = 0; i < n - 1; i++) {
		StringTokenizer st = new StringTokenizer(br.readLine());
		int a = Integer.parseInt(st.nextToken());
		int b = Integer.parseInt(st.nextToken());
		adj[a].add(b);
		adj[b].add(a);
	}

	maxLog = (int) (Math.log(n) / Math.log(2)) + 1;
	dp = new int[n + 1][maxLog];
	depth = new int[n + 1];

	dfs(1, 0);

	for (int j = 1; j < maxLog; j++) {
		for (int i = 1; i <= n; i++) {
			dp[i][j] = dp[dp[i][j - 1]][j - 1];
		}
	}

	int queries = Integer.parseInt(br.readLine());
	for (int i = 0; i < queries; i++) {
		StringTokenizer st = new StringTokenizer(br.readLine());
		int a = Integer.parseInt(st.nextToken());
		int b = Integer.parseInt(st.nextToken());
		result.append(lca(a, b)).append("\n");
	}

	bw.write(result.toString());
	bw.flush();
}

private static void dfs(int node, int parent) {
	depth[node] = depth[parent] + 1;
	dp[node][0] = parent;

	for (int next : adj[node]) {
		if (next != parent) {
			dfs(next, node);
		}
	}
}

private static int lca(int a, int b) {
	if (depth[a] < depth[b]) {
		int temp = a;
		a = b;
		b = temp;
	}

	int diff = depth[a] - depth[b];
	for (int i = 0; i < maxLog; i++) {
		if ((diff & (1 << i)) > 0) {
			a = dp[a][i];
		}
	}

	if (a == b) {
		return a;
	}

	for (int i = maxLog - 1; i >= 0; i--) {
		if (dp[a][i] != dp[b][i]) {
			a = dp[a][i];
			b = dp[b][i];
		}
	}

	return dp[a][0];
}

출처:https://www.acmicpc.net/problem/11438

0개의 댓글