import java.io.*; import java.util.*; public clas...
創建於:2025年6月23日
使用 O4 Mini High 回答 Chat01
創建於:2025年6月23日
使用 O4 Mini High 回答 Chat01
import java.io.;
import java.util.;
public class Main {
static class Edge { int u, v; Edge(int u, int v){ this.u = u; this.v = v; } }
static int n;
static List<Integer>[] adj;
static List<Edge> ans;
textpublic static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(System.out); int t = Integer.parseInt(in.readLine().trim()); while (t-- > 0) { n = Integer.parseInt(in.readLine().trim()); adj = new ArrayList[n+1]; for (int i = 1; i <= n; i++) adj[i] = new ArrayList<>(); for (int i = 0; i < n-1; i++) { String[] uv = in.readLine().split(" "); int u = Integer.parseInt(uv[0]), v = Integer.parseInt(uv[1]); adj[u].add(v); adj[v].add(u); } int center = -1; for (int i = 1; i <= n; i++) { if (adj[i].size() == 2) { center = i; break; } } if (center == -1) { out.println("NO"); continue; } int a = adj[center].get(0); int b = adj[center].get(1); ans = new ArrayList<>(n-1); ans.add(new Edge(a, center)); ans.add(new Edge(center, b)); dfsOrient(a, center, false); dfsOrient(b, center, true); out.println("YES"); StringBuilder sb = new StringBuilder(); for (Edge e : ans) { sb.append(e.u).append(' ').append(e.v).append('\n'); } out.print(sb); } out.flush(); } static void dfsOrient(int root, int block, boolean flip) { Deque<int[]> stack = new ArrayDeque<>(); for (int nei : adj[root]) { if (nei == block) continue; stack.push(new int[]{nei, root, 1}); } while (!stack.isEmpty()) { int[] cur = stack.pop(); int u = cur[0], p = cur[1], d = cur[2]; boolean odd = (d & 1) == 1; if (odd ^ flip) { ans.add(new Edge(p, u)); } else { ans.add(new Edge(u, p)); } for (int v : adj[u]) { if (v == p) continue; stack.push(new int[]{v, u, d+1}); } } }
}
use List<List<Integer>> and also try if it can be further simplified keeping time complexity same
Here’s a refactored version that uses a List<List<Integer>>
for the adjacency, replaces your manual stack DFS with a clean recursive method, and avoids raw arrays. The time complexity remains O(n):
javaimport java.io.*; import java.util.*; public class Main { static class Edge { int u, v; Edge(int u, int v){ this.u = u; this.v = v; } } public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(System.out); int t = Integer.parseInt(in.readLine().trim()); while (t-- > 0) { int n = Integer.parseInt(in.readLine().trim()); // build adjacency as List<List<Integer>> List<List<Integer>> adj = new ArrayList<>(n+1); for (int i = 0; i <= n; i++) adj.add(new ArrayList<>()); for (int i = 0; i < n - 1; i++) { String[] uv = in.readLine().split(" "); int u = Integer.parseInt(uv[0]), v = Integer.parseInt(uv[1]); adj.get(u).add(v); adj.get(v).add(u); } // find a "center" node of degree 2 int center = -1; for (int i = 1; i <= n; i++) { if (adj.get(i).size() == 2) { center = i; break; } } if (center == -1) { out.println("NO"); continue; } // the two neighbors of center List<Integer> nbrs = adj.get(center); int a = nbrs.get(0), b = nbrs.get(1); // prepare answer list List<Edge> ans = new ArrayList<>(n - 1); // fix the two central edges as in your original logic: ans.add(new Edge(a, center)); // a → center ans.add(new Edge(center, b)); // center → b // recursively orient the rest dfs(a, center, false, adj, ans); dfs(b, center, true, adj, ans); out.println("YES"); for (Edge e : ans) { out.println(e.u + " " + e.v); } } out.flush(); } /** * @param u current node * @param p parent in the DFS * @param flip whether to invert orientation at odd depths * (mirrors your original `flip` flag) * @param adj adjacency list * @param ans list to accumulate oriented edges */ static void dfs(int u, int p, boolean flip, List<List<Integer>> adj, List<Edge> ans) { for (int v : adj.get(u)) { if (v == p) continue; // distance from the center is "depth"; first call is depth=1 (odd) // so we track parity by toggling flip at each step: // odd depth ⊕ flip tells us whether to do p→v (true) or v→p (false) boolean dir = flip ^ true; if (dir) { ans.add(new Edge(u, v)); } else { ans.add(new Edge(v, u)); } // for children, depth parity flips, so we invert flip for next level dfs(v, u, !flip, adj, ans); } } }
What changed:
List<List<Integer>>
adjacency instead of List<Integer>[]
—avoids unchecked warnings and is more idiomatic with generics.dfs
replaces your explicit stack; depth parity is tracked by flipping a boolean on each call.n
, adj
, ans
) instead of statics where possible, making the method cleaner and thread-safer.