1

Question:

Given an undirected tree with N nodes ( 2 <= N <= 100,000 ) and N-1 edges, how can I find two non-intersecting paths with maximum product?

Example:

6

1-2

2-3

2-4

5-4

6-4

Answer: 4

I need to find O(N) solution. I wrote O(n^2) solution, but it isn’t accepting it. Here is my O(n^2) solution:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main{
    private static int currentMax;
    private static List<List<Integer>> tree;

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader("src/input.txt"));
        int N = Integer.parseInt(reader.readLine()) - 1;
        int[][] edges = new int[N][2];
        tree = new ArrayList<>();

        for (int i = 0; i < N; i++) {
            String[] line = reader.readLine().split(" ");
            edges[i][0] = Integer.parseInt(line[0]);
            edges[i][1] = Integer.parseInt(line[1]);
        }

        for(int i = 0; i < N + 2; i++)
            tree.add(i, new ArrayList<>());

        for (int[] edge : edges) {
            tree.get(edge[0]).add(edge[1]);
            tree.get(edge[1]).add(edge[0]);
        }

        long res = 0;
        int path1, path2;
        for(int i = 1; i < N + 2; i++) {
            for(int j = 0; j < tree.get(i).size(); j++) {
                currentMax = 0;
                path1 = dfs(tree.get(i).get(j), i);
                currentMax = 0;
                path2 = dfs(i, tree.get(i).get(j));
                res = Math.max(res, (long) path1 * path2);
            }
            System.out.println(i);
        }

        System.out.println(res);
        reader.close();
    }


    private static int dfs(int root, int visited) {
        int fisrtMax = 0, secMax = 0;
        int total = 0;
        for(int i = 0; i < tree.get(root).size(); i++) {
            if (tree.get(root).get(i) == visited)
                continue;
            total = Math.max(total, dfs(tree.get(root).get(i), root));
            if (currentMax > fisrtMax) {
                secMax = fisrtMax;
                fisrtMax = currentMax;
            } else if(currentMax > secMax)
                secMax = currentMax;
        }
        if (fisrtMax + secMax > total)
            total = fisrtMax + secMax;

        currentMax = fisrtMax + 1;
        return total;
    }
}
4
  • 1
    Why the answer to the example is 4? Could you please explain it? Commented Nov 25, 2024 at 20:35
  • 1
    What is a "undirected tree?" A tree is a directed graph. Did you mean undirected graph? Commented Nov 25, 2024 at 20:36
  • 2
    You say, "I wrote O(n^2) solution, but it isn’t accepting it." What isn't accepting your solution? Does your algorithm produce incorrect results? Also, it's not clear what your example illustrates. I assume that the numbers (i.e. 1-2) mean that there is an edge between vertices 1 and 2. You should show that data, and also show the tree that it represents. You also say you want a "maximum product," but I don't see you computing a product anywhere. So it's unclear to me what problem you're trying to solve and what help you want from us. Commented Nov 25, 2024 at 21:26
  • 1
    @JimMischel A tree is undirected by any textbook definition. Directed trees (and their subclass arborescences, which might be what you're thinking of here) exist, but they're a different class of graphs. Commented Nov 26, 2024 at 20:57

1 Answer 1

1

From your code, I understood that you want the maximum product of lengths of any two non-vertex-intersecting paths.

In your DFS, for each subtree defined by an edge and one of its possible directions (2N subtrees in total), you're computing only two values: the maximum distance of a vertex from the root of the subtree and the maximum length of a path in the subtree, i.e. its diameter. This is a correct idea, you just need to compute them more efficiently - you're recomputing these O(N) values many times.

Simple memoization should be sufficient. You can implement it using a list of 2N pairs (max dist, diameter), one for each endpoint of an edge in the order in which they're given on the input. There's a neat implementation trick here: consider that if root is the (2i+k)-th of these values (k = 0 or 1), then visited is the other endpoint of edge i, which is the (2i+1-k)-th value. You should use this "directed edge index" for everything - adjacency graph, sole argument of dfs(), checking if you're trying to go back the same way you came... and said memoization of dfs outputs. Other than these changes, your code is correct in principle.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.