---
# System prepended metadata

title: 'Orange lecture #1 - Book of Evil'

---

# Orange lecture #1 - Book of Evil

### 1, Đề bài
- n khu chỗ ở, n - 1 đường đi 2 chiều kết nối tất cả khu này -> cây vô hướng
- Book of Evil có phạm phi phá huỷ là d, các node bị ảnh hưởng là  p[1], p[2], ..., p[m] -> tìm tất cả vị trí có khả năng đặt Book of Evil

Input:
- n, m, d
- p1, p2, ..., pm
- n - 1: dòng 
	+ u v

Output:
- Số lượng vị trí đặt Book of Evil

### 2, Ý tưởng & giải thuật
a) Bruteforce
- for u = 1 -> n: bfs(u)
  	check dist(u, p[1]) <= d && ... dist(u, p[m]) <= d
       => result += 1

=> O(N^2)
 
b) AC Solution
- Nhận xét:
+ Tìm cặp **s = p[i] - p[j] = r** xa nhau nhất trong số các node bị ảnh hưởng
+ Book of Evil gây ảnh hưởng tới cả 2 node này <=> Book Of Evil gây ảnh hưởng tới tất cả p[i]
**Chứng minh:**
![](https://i.imgur.com/Q3XxGkk.png)
Gọi t là vị trí đặt Book of Evil, s & r là cặp đỉnh bị ảnh hưởng xa nhau nhất, dist(t, s) <= d & dist(t, r) <= d
Giả sử tồn tại một đỉnh bị ảnh hưởng x mà dist(t, x) > d (*)
=> dist(s, x) = dist(s,t) + dist(t, x) > dist(s,t) + d >= dist(s, t) + dist(r, t) = dist(s, r) => (s, x) mới là cặp đỉnh bị ảnh hưởng xa nhau nhất, mẫu thuẫn với giả thiết (s, r) là cặp đỉnh bị ảnh hưởng xa nhau nhất => Mệnh đề (\*) bị bác bỏ

#### **Thuật toán:**
+ B1: Tìm cặp đỉnh đặc biệt/bị ảnh hưởng xa nhau nhất s, r
  - Chọn 1 đỉnh p[j] bất kì -> tìm đỉnh bị ảnh hưởng cách xa p[j] nhất, gọi đỉnh này là q => ta khẳng định được: q hoặc là s hoặc là r (**)
  - Từ s = q, tìm đỉnh bị ảnh hưởng xa nhất -> đỉnh đó là r
> **Chứng minh:**
> ![](https://i.imgur.com/9CctD7E.png)
Giả sử q không là một trong 2 node bị ảnh hưởng cách xa nhau nhất.  Ta dựng cây gốc p[j]:
             Đặt p = lca(s, r) # lowest common ancestor
             Đặt k = lca(s, r, q)
             => giả sử s là đỉnh có lca(s, q) = k # Chắc chắn một trong 2 đỉnh s, r khi lấy lca với q thì sẽ tạo ra k, ở đây ta giả sử nó là s
             dist(s, r) = dist(s, p) + dist(p, r) <= dist(s, k) + dist(k, r)
             <= dist(s, k) + [ dist(p[j], r) - dist(p[j], k) ] <= dist(s,k) + [dist(p[j], q) - dist(p[j], k)] = dist(s,k) + dist(q, k) = dist(s, q)
               => Như vậy q nằm trong cặp đỉnh bị ảnh hưởng cách xa nhau nhất -> mẫu thuẫn

=> Tóm lại: q LÀ một trong 2 node bị ảnh hưởng cách xa nhau nhất

- B2: Tìm tất cả các đỉnh có khoảng cách <= d đến hai đỉnh s,r -> Kết quả bài toán
  
  
### 3, Mã giả
```python=
graph[i] = {}
n, m, d = readInt(), readInt(), readInt()
p = readArrInt()
for i = 1 -> n - 1:
	u, v = readInt(), readInt()
  graph[u].add(v)
  graph[v].add(u)
    
#
x = p[0]
bfs(x)
q = -1 # find q
for i = 0 -> m - 1:
	if(q < 0 or dist(x, p[i]) > dist(x, q)):
      q = p[i]
      
s = q
#find r
bfs(s)
r = -1
for i = 0 -> m - 1:
	if(r < 0 or dist(s, p[i]) > dist(s, r)):
      r = p[i]

# s - r
# bfs(s)
bfs(r)

# find all vertices t | dist(s, t) <= d & dist(r, t) <= d
result = 0
for i = 1 -> n:
    if(dist(s, i) <= d & dist(r, i) <= d):
				result += 1
          
print(result)
```

### 4, Độ phức tạp
- **O(N)**