UDPC G번 문제로 그래프에서 정점 위치별 거리를 파악하면 되는 문제이다. 간단하지만 하나의 아이디어로 시간복잡도를 줄일 수 있기에 글을 써본다.
정점 개의 정점이 주어지고 개의 간선이 주어진다. 번 라인에는 윤이, 달구 그리 고 포닉스가 시작하는 위치가 주어지는데 각 노드의 위치에서 Leaf(간선의 개수가 1인)인 정점까지 도착하는 최단 거리를 측정한 뒤(거리는 dfs 또는 bfs 아무거나 써도 된다) 각 Leaf 노드를 돌면서 윤이의 거리가 두 명의 거리보다 짧다면 정답이 나온다.(거리가 같은 경우는 무슨 경우일까? 아래에서 확인해보자)
이 부분을 생각을 조금 많이 했다. 거리가 짧은 경우만 확인해도 될까? 내가 생각한 경우가 부족할 수 있지만 생각한 내용들을 적어본다.
using namespace std;int n;int d1[N], d2[N], d3[N];int qs[3];vector<int> a[N];set<int> leaf;void dfs(int cur, int depth, int d[]) {if (a[cur].size() == 1) {leaf.insert(cur);}for (auto nn : a[cur]) {if (d[nn] > depth + 1) {d[nn] = depth + 1;dfs(nn, depth + 1, d);}}}void input() {cin >> n;for (int i = 0; i < n - 1; i++) {int l, r;cin >> l >> r;l--;r--;a[l].push_back(r);a[r].push_back(l);}for (int i = 0; i < 3; i++) {cin >> qs[i];qs[i]--;}}int solve() {input();fill_n(d1, n, MAX);fill_n(d2, n, MAX);fill_n(d3, n, MAX);d1[qs[0]] = 0;dfs(qs[0], 0, d1);d2[qs[1]] = 0;dfs(qs[1], 0, d2);d3[qs[2]] = 0;dfs(qs[2], 0, d3);for (auto q : leaf) {if (d1[q] < d2[q] && d1[q] < d3[q]) {cout << "YES\n";return 0;}}cout << "NO\n";return 0;}int main() {FAST;solve();return 0;}
import enumfrom sys import stdin, maxsize, setrecursionlimitfrom heapq import *from bisect import *from collections import dequeimport randomfrom itertools import combinationsMAX = 17MOD = 1000000007setrecursionlimit(10**6)input = stdin.readlineN = int(input())a =[[] for _ in range(N+1)]for _ in range(N-1):l, r = map(int, input().split())a[l].append(r)a[r].append(l)qs = list(map(int, input().split()))def main():# ( pos, isYun: 1=yun, 2=others)q = deque([(qs[1], 2), (qs[2], 2), (qs[0], 1)])v = [0] * (N + 1) # v is visited arrayv[qs[0]] = 1;v[qs[1]] = 2;v[qs[2]] = 2while q:pos, is_yun = q.popleft()if is_yun == 1 and len(a[pos]) == 1:print('YES');return;for nn in a[pos]: # nn is next_nodeif not v[nn]:v[nn] = is_yunq.append((nn, is_yun))print('NO');return;if __name__ == '__main__':main()