import java.io.*; import java.util.*; public class Main { public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(reader.readLine()); int n = Integer.parseInt(st.nextToken()); int s = Integer.parseInt(st.nextToken()); List<Integer>[] adj = new ArrayList[n + 1]; for (int i = 1; i <= n; i++) { adj[i] = new ArrayList<>(); } for (int i = 0; i < n - 1; i++) { st = new StringTokenizer(reader.readLine()); int x = Integer.parseInt(st.nextToken()); int y = Integer.parseInt(st.nextToken()); adj[x].add(y); adj[y].add(x); } List<Integer>[] children = new ArrayList[n + 1]; for (int i = 1; i <= n; i++) { children[i] = new ArrayList<>(); } int[] parent = new int[n + 1]; Arrays.fill(parent, -1); Queue<Integer> queue = new LinkedList<>(); queue.add(s); parent[s] = 0; while (!queue.isEmpty()) { int u = queue.poll(); for (int v : adj[u]) { if (parent[v] == -1) { parent[v] = u; children[u].add(v); queue.add(v); } } } int[] dp0 = new int[n + 1]; int[] dp1 = new int[n + 1]; Stack<Integer> stack = new Stack<>(); stack.push(s); boolean[] processed = new boolean[n + 1]; while (!stack.isEmpty()) { int u = stack.pop(); if (!processed[u]) { processed[u] = true; stack.push(u); for (int i = children[u].size() - 1; i >= 0; i--) { stack.push(children[u].get(i)); } } else { dp1[u] = 1; dp0[u] = 0; for (int v : children[u]) { dp1[u] += dp0[v]; dp0[u] += Math.max(dp0[v], dp1[v]); } } } System.out.println(dp1[s]); } }
https://www.nowcoder.com/discuss/727521113110073344
思路:
1.输入处理:使用BufferedReader和StringTokenizer高效读取输入数据,构建邻接表表示的树结构。
2.有根树构建:通过BFS遍历,以起始城市s为根,确定每个节点的父节点和子节点列表。
3.动态规划计算:使用栈模拟后序遍历,计算每个节点的dp0和dp1值,确保在处理每个节点时,其子节点已被处理完毕。
4.结果输出:输出起始城市s的dp1[s]值,即为包含s的最大独立集大小,即最多能度过的天数。