Dog Snacks (Codeforces 1453E)
Tags: Greedy, trees

Gildong is playing with his dog, Badugi. They're at a park that has $$$n$$$ intersections and $$$n-1$$$ bidirectional roads, each $$$1$$$ meter in length and connecting two intersections with each other. The intersections are numbered from $$$1$$$ to $$$n$$$, and for every $$$a$$$ and $$$b$$$ ($$$1 \le a, b \le n$$$), it is possible to get to the $$$b$$$-th intersection from the $$$a$$$-th intersection using some set of roads.Gildong has put one snack at every intersection of the park. Now Gildong will give Badugi a mission to eat all of the snacks. Badugi starts at the $$$1$$$-st intersection, and he will move by the following rules:  Badugi looks for snacks that are as close to him as possible. Here, the distance is the length of the shortest path from Badugi's current location to the intersection with the snack. However, Badugi's sense of smell is limited to $$$k$$$ meters, so he can only find snacks that are less than or equal to $$$k$$$ meters away from himself. If he cannot find any such snack, he fails the mission.  Among all the snacks that Badugi can smell from his current location, he chooses a snack that minimizes the distance he needs to travel from his current intersection. If there are multiple such snacks, Badugi will choose one arbitrarily.  He repeats this process until he eats all $$$n$$$ snacks. After that, he has to find the $$$1$$$-st intersection again which also must be less than or equal to $$$k$$$ meters away from the last snack he just ate. If he manages to find it, he completes the mission. Otherwise, he fails the mission. Unfortunately, Gildong doesn't know the value of $$$k$$$. So, he wants you to find the minimum value of $$$k$$$ that makes it possible for Badugi to complete his mission, if Badugi moves optimally.

Input: Each test contains one or more test cases. The first line contains the number of test cases $$$t$$$ ($$$1 \le t \le 10^4$$$).The first line of each test case contains one integer $$$n$$$ ($$$2 \le n \le 2 \cdot 10^5$$$) — the number of intersections of the park.The next $$$n-1$$$ lines contain two integers $$$u$$$ and $$$v$$$ ($$$1 \le u,v \le n$$$, $$$u \ne v$$$) each, which means there is a road between intersection $$$u$$$ and $$$v$$$. All roads are bidirectional and distinct.It is guaranteed that:   For each test case, for every $$$a$$$ and $$$b$$$ ($$$1 \le a, b \le n$$$), it is possible to get to the $$$b$$$-th intersection from the $$$a$$$-th intersection.  The sum of $$$n$$$ in all test cases doesn't exceed $$$2 \cdot 10^5$$$. 

Output: For each test case, print one integer — the minimum possible value of $$$k$$$ such that Badugi can complete the mission.

Note: In the first case, Badugi can complete his mission with $$$k=2$$$ by moving as follows:   Initially, Badugi is at the $$$1$$$-st intersection. The closest snack is obviously at the $$$1$$$-st intersection, so he just eats it.  Next, he looks for the closest snack, which can be either the one at the $$$2$$$-nd or the one at the $$$3$$$-rd intersection. Assume that he chooses the $$$2$$$-nd intersection. He moves to the $$$2$$$-nd intersection, which is $$$1$$$ meter away, and eats the snack.  Now the only remaining snack is on the $$$3$$$-rd intersection, and he needs to move along $$$2$$$ paths to get to it.  After eating the snack at the $$$3$$$-rd intersection, he needs to find the $$$1$$$-st intersection again, which is only $$$1$$$ meter away. As he gets back to it, he completes the mission. In the second case, the only possible sequence of moves he can make is $$$1$$$ – $$$2$$$ – $$$3$$$ – $$$4$$$ – $$$1$$$. Since the distance between the $$$4$$$-th intersection and the $$$1$$$-st intersection is $$$3$$$, $$$k$$$ needs to be at least $$$3$$$ for Badugi to complete his mission.In the third case, Badugi can make his moves as follows: $$$1$$$ – $$$5$$$ – $$$6$$$ – $$$7$$$ – $$$8$$$ – $$$2$$$ – $$$3$$$ – $$$4$$$ – $$$1$$$. It can be shown that this is the only possible sequence of moves for Badugi to complete his mission with $$$k=3$$$.  

Sample Inputs:
3
3
1 2
1 3
4
1 2
2 3
3 4
8
1 2
2 3
3 4
1 5
5 6
6 7
5 8

Sample Outputs:
2
3
3

Solution (Python):
import sys
input = sys.stdin.readline

def solve():
    n = int(input())
    g = [[] for i in range(n)]
    for i in range(n - 1):
        (u, v) = map(int, input().split())
        g[u - 1].append(v - 1)
        g[v - 1].append(u - 1)
    q = [0]
    p = [-1] * n
    d = [0] * n
    for i in range(n):
        x = q[i]
        P = p[x]
        for v in g[x]:
            if v != P:
                p[v] = x
                q.append(v)
    r = 0
    for i in range(n - 1, -1, -1):
        x = q[i]
        P = p[x]
        u = 10000000
        w = 10000000
        y = -1
        for v in g[x]:
            if P != v:
                if d[v] < u:
                    (u, w) = (d[v], u)
                elif d[v] < w:
                    w = d[v]
                y = max(y, d[v])
        if P != -1:
            if u == 10000000:
                d[x] = 0
            elif w == 10000000:
                d[x] = u + 1
            else:
                d[x] = u + 1
                r = max(r, y + 2)
        elif u == 10000000:
            d[x] = 0
        elif w == 10000000:
            d[x] = u + 1
            r = max(r, u + 1)
        else:
            d[x] = u + 1
            e = [d[v] for v in g[x]]
            e.sort()
            if e[-1] != e[-2]:
                r = max(r, e[-1] + 1)
            else:
                r = max(r, e[-1] + 2)
    print(r)
for i in range(int(input())):
    solve()

Solution (Python):
import sys
input = sys.stdin.readline

def solve():
    n = int(input())
    g = [[] for i in range(n)]
    for i in range(n - 1):
        (u, v) = map(int, input().split())
        g[u - 1].append(v - 1)
        g[v - 1].append(u - 1)
    q = [0]
    p = [-1] * n
    d = [0] * n
    for i in range(n):
        x = q[i]
        P = p[x]
        for v in g[x]:
            if v != P:
                p[v] = x
                q.append(v)
    r = 0
    for i in range(n - 1, -1, -1):
        x = q[i]
        P = p[x]
        u = 10000000
        y = -1
        for v in g[x]:
            if P != v:
                u = min(u, d[v])
                y = max(y, d[v])
        if P != -1:
            l = len(g[x])
            if l == 1:
                d[x] = 0
            elif l == 2:
                d[x] = u + 1
            else:
                d[x] = u + 1
                r = max(r, y + 2)
        else:
            l = len(g[x])
            if l == 0:
                d[x] = 0
            elif l == 1:
                d[x] = u + 1
                r = max(r, u + 1)
            else:
                d[x] = u + 1
                u = -1
                w = -1
                for v in g[x]:
                    if d[v] > u:
                        (u, w) = (d[v], u)
                    elif d[v] > w:
                        w = d[v]
                if u != w:
                    r = max(r, u + 1)
                else:
                    r = max(r, u + 2)
    print(r)
for i in range(int(input())):
    solve()

Solution (Python):
import sys
input = sys.stdin.readline

def solve():
    n = int(input())
    g = [[] for i in range(n)]
    for i in range(n - 1):
        (u, v) = map(int, input().split())
        g[u - 1].append(v - 1)
        g[v - 1].append(u - 1)
    q = [0]
    p = [-1] * n
    d = [0] * n
    for i in range(n):
        x = q[i]
        P = p[x]
        for v in g[x]:
            if v != P:
                p[v] = x
                q.append(v)
    r = 0
    for i in range(n - 1, -1, -1):
        x = q[i]
        P = p[x]
        u = 10000000
        y = -1
        for v in g[x]:
            if P != v:
                u = min(u, d[v])
                y = max(y, d[v])
        if P != -1:
            l = len(g[x])
            if l == 1:
                d[x] = 0
            elif l == 2:
                d[x] = u + 1
            else:
                d[x] = u + 1
                r = max(r, y + 2)
        else:
            l = len(g[x])
            if l == 0:
                d[x] = 0
            elif l == 1:
                d[x] = u + 1
                r = max(r, u + 1)
            else:
                d[x] = u + 1
                u = -1
                w = -1
                for v in g[x]:
                    if P != v:
                        if d[v] > u:
                            (u, w) = (d[v], u)
                        elif d[v] > w:
                            w = d[v]
                if u != w:
                    r = max(r, u + 1)
                else:
                    r = max(r, u + 2)
    print(r)
for i in range(int(input())):
    solve()