Bird
Raised Fist0
DSA Cprogramming~10 mins

DP on Trees Diameter of Tree in DSA C - Execution Trace

Choose your learning style10 modes available
Concept Flow - DP on Trees Diameter of Tree
Start at any node
↓
DFS to children
↓
Compute max depths from children
↓
Update diameter using top two depths
↓
Return max depth to parent
↓
Repeat for all nodes
↓
Final diameter is max found
We start DFS from any node, compute max depths from children, update diameter using top two depths, and return max depth to parent until all nodes are processed.
Execution Sample
DSA C
int dfs(int node, int parent) {
  int max1 = 0, max2 = 0;
  for (each child of node) {
    if (child != parent) {
      int depth = dfs(child, node);
      if (depth > max1) { max2 = max1; max1 = depth; } else if (depth > max2) max2 = depth;
    }
  }
  diameter = max(diameter, max1 + max2);
  return max1 + 1;
}
This code runs DFS to find max depths from children, updates diameter with sum of top two depths, and returns max depth to parent.
Execution Table
StepOperationNode VisitedMax Depths from ChildrenDiameter UpdateReturn DepthVisual State
1Start DFSNode 1max1=0, max2=0diameter=0Returns after children1
2DFS child Node 2Node 2max1=0, max2=0diameter=0Returns 11 -> 2
3Update Node 1 depthsNode 1max1=1, max2=0diameter=1Returns 21 -> 2
4DFS child Node 3Node 3max1=0, max2=0diameter=1Returns 11 -> 2, 1 -> 3
5Update Node 1 depthsNode 1max1=1, max2=1diameter=2Returns 21 -> 2, 1 -> 3
6DFS child Node 4Node 4max1=0, max2=0diameter=2Returns 11 -> 2, 1 -> 3, 3 -> 4
7Update Node 3 depthsNode 3max1=1, max2=0diameter=2Returns 21 -> 2, 1 -> 3, 3 -> 4
8Update Node 1 depthsNode 1max1=2, max2=1diameter=3Returns 31 -> 2, 1 -> 3, 3 -> 4
9DFS child Node 5Node 5max1=0, max2=0diameter=3Returns 13 -> 5
10Update Node 3 depthsNode 3max1=1, max2=1diameter=3Returns 23 -> 4, 3 -> 5
11Update Node 1 depthsNode 1max1=2, max2=2diameter=4Returns 31 -> 2, 1 -> 3, 3 -> 4, 3 -> 5
12End DFSNode 1max1=2, max2=2diameter=4Final diameter=4Full tree
💡 All nodes visited, diameter updated with max sum of two depths, DFS ends.
Variable Tracker
VariableStartAfter Step 2After Step 5After Step 8After Step 11Final
diameter002344
max1 (Node 1)011222
max2 (Node 1)001122
Return Depth (Node 1)N/A22333
Key Moments - 3 Insights
Why do we keep track of two maximum depths (max1 and max2) at each node?
Because the diameter can pass through the current node combining two longest paths from different children. See execution_table steps 5 and 11 where diameter updates use max1 + max2.
Why do we return max1 + 1 from the DFS function?
We return max1 + 1 to represent the longest path from current node down to a leaf including the current node itself. This is shown in execution_table steps 3, 5, 8, and 11.
Why do we ignore the parent node in DFS traversal?
To avoid revisiting the node we came from and prevent infinite loops. This is implied in the code and shown in execution_table where children are visited excluding parent.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 5, what is the diameter value after updating Node 1?
A2
B1
C3
D0
💡 Hint
Check the 'Diameter Update' column at step 5 in execution_table.
At which step does the diameter first become 4?
AStep 8
BStep 6
CStep 11
DStep 12
💡 Hint
Look at the 'Diameter Update' column in execution_table rows for diameter=4.
If we did not track max2 (second max depth), what would be the diameter after step 11?
A4
B3
C2
D1
💡 Hint
Without max2, diameter updates use only max1, see how diameter changes in execution_table.
Concept Snapshot
DP on Trees Diameter:
- Use DFS from any node
- Track top two max depths from children
- Update diameter = max(diameter, max1 + max2)
- Return max1 + 1 to parent
- Diameter is longest path between any two nodes
Full Transcript
We find the diameter of a tree using dynamic programming with DFS. Starting from any node, we explore children and compute the maximum depths from them. At each node, we keep track of the two largest depths (max1 and max2). The diameter is updated by the sum of these two depths, representing the longest path passing through that node. We return max1 + 1 to the parent to represent the longest path including the current node. This process repeats until all nodes are visited, and the maximum diameter found is the tree's diameter.

Practice

(1/5)
1. What is the diameter of a tree in the context of dynamic programming on trees?
easy
A. The height of the tree from the root
B. The number of nodes in the tree
C. The sum of all edge weights in the tree
D. The longest path between any two nodes in the tree

Solution

  1. Step 1: Understand the definition of tree diameter

    The diameter is the longest path between any two nodes in the tree, not just from the root.
  2. Step 2: Differentiate from other tree properties

    Height is from root to leaf, sum of edges is total weight, and node count is size, none represent longest path.
  3. Final Answer:

    The longest path between any two nodes in the tree -> Option D
  4. Quick Check:

    Diameter = Longest path [OK]
Hint: Diameter is longest path between any two nodes [OK]
Common Mistakes:
  • Confusing diameter with height
  • Thinking diameter is number of nodes
  • Assuming diameter is sum of all edges
2. Which of the following is the correct way to declare an adjacency list for a tree with n nodes in C?
easy
A. int adj[n][n];
B. int* adj[n];
C. int adj[n];
D. int adjList[n][2];

Solution

  1. Step 1: Understand adjacency list structure

    An adjacency list uses an array of pointers to lists (or arrays) of neighbors, so int* adj[n]; is correct.
  2. Step 2: Differentiate from other declarations

    int adj[n][n]; is adjacency matrix, int adj[n]; is a simple array, int adjList[n][2]; is edge list, not adjacency list.
  3. Final Answer:

    int* adj[n]; -> Option B
  4. Quick Check:

    Adjacency list uses array of pointers [OK]
Hint: Adjacency list uses array of pointers to neighbors [OK]
Common Mistakes:
  • Using 2D array as adjacency list
  • Using simple array for adjacency
  • Confusing edge list with adjacency list
3. Consider the following C code snippet to find the diameter of a tree. What will be the output if the tree has edges: 1-2, 2-3, 2-4?
int diameter = 0;
int dfs(int node, int parent, vector<int> adj[]) {
    int max1 = 0, max2 = 0;
    for (int child : adj[node]) {
        if (child == parent) continue;
        int height = dfs(child, node, adj) + 1;
        if (height > max1) {
            max2 = max1;
            max1 = height;
        } else if (height > max2) {
            max2 = height;
        }
    }
    diameter = max(diameter, max1 + max2);
    return max1;
}
// Call dfs(1, -1, adj) and then print diameter;
medium
A. 2
B. 3
C. 1
D. 4

Solution

  1. Step 1: Trace DFS from node 1

    From node 1, child is 2. DFS(2) explores children 3 and 4. Heights from 3 and 4 are 1 each.
  2. Step 2: Calculate diameter updates

    At node 2, max1=1, max2=1, diameter updated to 2. At node 1, max1=2, max2=0, diameter remains 2.
  3. Final Answer:

    2 -> Option A
  4. Quick Check:

    Longest path length = 2 edges [OK]
Hint: Diameter = sum of two longest child heights [OK]
Common Mistakes:
  • Counting nodes instead of edges
  • Not updating diameter correctly
  • Ignoring parent to avoid cycles
4. The following code attempts to compute the diameter of a tree but produces incorrect results. What is the bug?
int diameter = 0;
int dfs(int node, int parent, vector<int> adj[]) {
    int max1 = 0, max2 = 0;
    for (int child : adj[node]) {
        int height = dfs(child, node, adj) + 1;
        if (height > max1) {
            max2 = max1;
            max1 = height;
        } else if (height > max2) {
            max2 = height;
        }
    }
    diameter = max(diameter, max1 + max2);
    return max1;
}
// Called with dfs(1, -1, adj);
medium
A. Incorrect initialization of diameter variable
B. Returning max2 instead of max1 from DFS
C. Missing check to skip parent node in DFS
D. Not adding 1 to height in DFS call

Solution

  1. Step 1: Identify missing parent check in DFS loop

    The code does not skip the parent node, causing infinite recursion or wrong heights.
  2. Step 2: Explain impact of missing check

    Without skipping parent, DFS revisits parent, causing incorrect diameter calculation or stack overflow.
  3. Final Answer:

    Missing check to skip parent node in DFS -> Option C
  4. Quick Check:

    Skip parent to avoid cycles [OK]
Hint: Always skip parent node in DFS to prevent cycles [OK]
Common Mistakes:
  • Forgetting to skip parent node
  • Returning wrong height value
  • Incorrect diameter initialization
5. Given a weighted tree with edges: (1-2, 3), (2-3, 4), (2-4, 2), how would you modify the diameter calculation to find the longest weighted path? Choose the correct approach.
hard
A. Add edge weights to height calculations and update diameter with weighted sums
B. Ignore weights and use number of edges as diameter
C. Multiply edge weights instead of adding
D. Use BFS twice without considering weights

Solution

  1. Step 1: Incorporate edge weights in DFS height calculation

    Instead of adding 1 for each edge, add the actual edge weight to the height returned by DFS.
  2. Step 2: Update diameter with sum of two largest weighted heights

    Keep track of two largest weighted heights from children and update diameter with their sum.
  3. Final Answer:

    Add edge weights to height calculations and update diameter with weighted sums -> Option A
  4. Quick Check:

    Weighted diameter sums edge weights [OK]
Hint: Add weights to heights, sum two largest for diameter [OK]
Common Mistakes:
  • Ignoring weights in diameter calculation
  • Multiplying weights instead of adding
  • Using unweighted BFS for weighted tree
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard