import java.io.*; import java.util.*; public clas...

Criado em: 23 de junho de 2025

Respondido usando O4 Mini High por Chat01

Pergunta

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;

text
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) { 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

Pensamento

Refactoring Java code

The user wants to refactor Java code, replacing List<Integer>[] with List<List<Integer>> and simplifying it while maintaining the same time complexity. I'll suggest using recursion instead of a manual stack and removing the static ans variable for better scoping. To handle edges, replacing Pair with a custom Edge record could work well. Also, using List<List<Integer>> for adjacency might streamline the code. I'll make sure to provide that updated code, no need for file searches or canvases.

Simplifying code structure

I'm thinking about how to reduce redundant code and simplify the DFS method. First, for center detection, I’ll use streams to filter the list and identify the center of the tree. Then, the DFS function can be simplified by passing in parameters for starting depth and flip state. I'll also switch to List<List<Integer>> for adjacency and result storage. The goal is to maintain the same time complexity. For edge orientation, I plan on implementing depth parity rather than tracking depth directly, flipping the state each time. Let me work this out in code.

Thought for 8 seconds

Resposta

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):

java
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; } } 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:

  1. List<List<Integer>> adjacency instead of List<Integer>[]—avoids unchecked warnings and is more idiomatic with generics.
  2. Single recursive dfs replaces your explicit stack; depth parity is tracked by flipping a boolean on each call.
  3. Local variables (n, adj, ans) instead of statics where possible, making the method cleaner and thread-safer.
  4. No change to overall time complexity (still one pass over each edge).

Compartilhar esta Q&A