#include #include #include #include using namespace std; const int MAXN = 100005; vector adj[MAXN]; vector children[MAXN]; int parent[MAXN], depth[MAXN], subtree_size[MAXN]; int n, k; void build_tree(int u, int p, int d) { parent[u] = p; depth[u] = d; for (int v : adj[u]) { if (v != p) { children[u].push_back(v); build_tree(v, u, d + 1); } } } void dfs_size(int u) { subtree_size[u] = 1; for (int v : children[u]) { dfs_size(v); subtree_size[u] += subtree_size[v]; } } // Case 1: BFS -> DFS long long pos_bfs[MAXN]; void compute_bfs_pos() { queue q; q.push(1); vector visited(n + 1, false); visited[1] = true; long long current_pos = 1; while (!q.empty()) { int u = q.front(); q.pop(); pos_bfs[u] = current_pos++; for (int v : children[u]) { if (!visited[v]) { visited[v] = true; q.push(v); } } } } long long solve_bfs_dfs() { compute_bfs_pos(); long long min_pos = pos_bfs[k]; vector path; int curr = k; while (curr != 0) { path.push_back(curr); curr = parent[curr]; } reverse(path.begin(), path.end()); vector> child_ss_prefix_sum(n + 1); for (int i = 1; i <= n; ++i) { child_ss_prefix_sum[i].push_back(0); long long current_sum = 0; for (int child : children[i]) { current_sum += subtree_size[child]; child_ss_prefix_sum[i].push_back(current_sum); } } long long current_dfs_count = 0; for (int i = path.size() - 2; i >= 0; --i) { int z = path[i]; int child_on_path = path[i + 1]; long long contrib = 0; for (int j = 0; j < children[z].size(); ++j) { if (children[z][j] == child_on_path) { contrib = 1 + (j > 0 ? child_ss_prefix_sum[z][j] : 0); break; } } current_dfs_count += contrib; min_pos = min(min_pos, pos_bfs[z] + current_dfs_count); } return min_pos; } // Case 2: DFS -> BFS long long pos_dfs[MAXN]; vector depth_nodes[MAXN]; void compute_dfs_pos_and_depths(int u, long long& current_pos) { pos_dfs[u] = ++current_pos; depth_nodes[u].push_back(depth[u]); for (int v : children[u]) { compute_dfs_pos_and_depths(v, current_pos); if (depth_nodes[v].size() > depth_nodes[u].size()) { swap(depth_nodes[u], depth_nodes[v]); } vector temp_v = depth_nodes[v]; depth_nodes[u].insert(depth_nodes[u].end(), temp_v.begin(), temp_v.end()); } // In a real contest, merging is better than re-sorting sort(depth_nodes[u].begin(), depth_nodes[u].end()); } long long query_depths(int u, int d_start, int d_end) { if (d_start > d_end) return 0; auto& vec = depth_nodes[u]; auto it1 = lower_bound(vec.begin(), vec.end(), d_start); auto it2 = upper_bound(vec.begin(), vec.end(), d_end); return distance(it1, it2); } long long solve_dfs_bfs() { long long initial_pos = 0; for(int i=1; i<=n; ++i) depth_nodes[i].clear(); compute_dfs_pos_and_depths(1, initial_pos); long long min_pos = pos_dfs[k]; vector path; int curr = k; while (curr != 0) { path.push_back(curr); curr = parent[curr]; } reverse(path.begin(), path.end()); vector> child_at_k_depth_prefix_sum(n + 1); for(int i=1; i<=n; ++i) { child_at_k_depth_prefix_sum[i].push_back(0); long long current_sum = 0; for(int child : children[i]) { current_sum += query_depths(child, depth[k], depth[k]); child_at_k_depth_prefix_sum[i].push_back(current_sum); } } long long nodes_before_k_less_depth = 0; long long nodes_before_k_at_depth = 0; for (int i = path.size() - 2; i >= 0; --i) { int z = path[i]; int child_on_path = path[i + 1]; long long added_less = query_depths(z, depth[child_on_path], depth[k] - 1) - query_depths(child_on_path, depth[child_on_path], depth[k] - 1); nodes_before_k_less_depth += added_less; long long added_at = 0; for(size_t j = 0; j < children[z].size(); ++j){ if(children[z][j] == child_on_path){ added_at = child_at_k_depth_prefix_sum[z][j]; break; } } nodes_before_k_at_depth += added_at; long long count_bfs = nodes_before_k_less_depth + nodes_before_k_at_depth; min_pos = min(min_pos, pos_dfs[z] + count_bfs + 1); } return min_pos; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n >> k; for (int i = 0; i < n - 1; ++i) { int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } build_tree(1, 0, 0); dfs_size(1); cout << solve_bfs_dfs() << endl; cout << solve_dfs_bfs() << endl; return 0; }