# Count of all possible Paths in a Tree such that Node X does not appear before Node Y

• Last Updated : 15 Sep, 2021

Given a Tree consisting of N nodes having values in the range [0, N – 1] and (N – 1) edges, and two nodes X and Y, the task is to find the number of possible paths in the Tree such that the node X does not appear before the node Y in the path.

Examples:

Input: N = 5, A = 2, B = 0, Edges[][] = { {0, 1}, {1, 2}, {1, 3}, {0, 4} }
Output: 18
Explanation:
Since (X, Y) and (Y, X) are being considered different, so the count of all possible paths connecting any two pairs of vertices = 2 * 5C2 = 20.
Out of these 20 pairs, those paths cannot be chosen, which consist of both nodes 2 and 0 as well as Node 2 appearing before Node 0.
There are two such paths (colored as green) which are shown below:

So there are total 20 – 2 = 18 such paths.

Input: N = 9, X = 5, Y = 3, Edges[][] = { {0, 2}, {1, 2}, {2, 3}, {3, 4}, {4, 6}, {4, 5}, {5, 7}, {5, 8} }
Output: 60
Explanation:
Since (X, Y) and (Y, X) are being considered different, so the count of all possible paths connecting any two pairs of vertices = N * (N – 1) = 9 * 8 = 72.
On observing the diagram below, any path starting from a Node in the subtree of Node 5, denoted by black, connecting to the vertices passing through the Node 3, denoted by green, will always have 5 appearing before 3 in the path. Therefore, total number of possible paths = (Total Nodes grouped in black) * (Total Nodes grouped in green) = 3 * 4 = 12.
Therefore, the final answer = 72 – 12 = 60

Approach:
The idea is to find the combination of node pairs that will always have the Node X appearing before Node Y in the path connecting them. Then, subtract the count of such pairs from the total number of possible node pairs = NC2. Consider node Y as the root node. Now any path which first encounters X and then Y, starts from the node in the subtree of node X and ends at a node in the sub-tree of node Y but not in the subtree of node W, where W is an immediate child of node Y and lies between X and Y in these paths.

Therefore, the final answer can be calculated by:

Count = N * (N – 1) – size_of_subtree(X) * (size_of_subtree(Y) – size_of_subtree(W))

If Y is taken as the root of the tree. Then, size_of_subtree(Y) = N.

Count = N * (N – 1) – size_of_subtree(X) * (N- size_of_subtree(W))

Follow the steps below to solve the problem:

1. Initialize arrays subtree_size [], visited [] and check_subtree [] each of size N + 1. Initialize elements of visited [] as 0.
2. Perform the DFS Traversal with Y as the root node to fill the check_subtree[] and subtree_size [] for each node. The check_subtree[] checks whether the subtree of the current node contains node X or not.
3. Find the child(say node v) of Y which is in the path from X to Y. Initialize an integer variable say difference.
4. Assign (total number of nodes – subtree_size[v] ) to difference.
5. Return (N * (N – 1) ) – (subtree_size[A] * (difference)) as the answer.

Below is the implementation of the above approach:

## C++

 `// C++ Program to implement``// the above approach``#include ``#define int long long int``using` `namespace` `std;` `// Maximum number of nodes``const` `int` `NN = 3e5;` `// Vector to store the tree``vector<``int``> G[NN + 1];` `// Function to perform DFS Traversal``int` `dfs(``int` `node, ``int` `A, ``int``* subtree_size,``        ``int``* visited, ``int``* check_subtree)``{``    ``// Mark the node as visited``    ``visited[node] = ``true``;` `    ``// Initialize the subtree size``    ``// of each node as 1``    ``subtree_size[node] = 1;` `    ``// If the node is same as A``    ``if` `(node == A) {` `        ``// Mark check_subtree[node] as true``        ``check_subtree[node] = ``true``;``    ``}` `    ``// Otherwise``    ``else``        ``check_subtree[node] = ``false``;` `    ``// Iterate over the adjacent nodes``    ``for` `(``int` `v : G[node]) {` `        ``// If the adjacent node``        ``// is not visited``        ``if` `(!visited[v]) {` `            ``// Update the size of the``            ``// subtree of current node``            ``subtree_size[node]``                ``+= dfs(v, A, subtree_size,``                       ``visited, check_subtree);` `            ``// Check if the subtree of``            ``// current node contains node A``            ``check_subtree[node] = check_subtree[node]``                                  ``| check_subtree[v];``        ``}``    ``}` `    ``// Return size of subtree of node``    ``return` `subtree_size[node];``}` `// Function to add edges to the tree``void` `addedge(``int` `node1, ``int` `node2)``{` `    ``G[node1].push_back(node2);``    ``G[node2].push_back(node1);``}` `// Function to calculate the number of``// possible paths``int` `numberOfPairs(``int` `N, ``int` `B, ``int` `A)``{``    ``// Stores the size of subtree``    ``// of each node``    ``int` `subtree_size[N + 1];` `    ``// Stores which nodes are``    ``// visited``    ``int` `visited[N + 1];` `    ``// Initialize all nodes as unvisited``    ``memset``(visited, 0, ``sizeof``(visited));` `    ``// Stores if the subtree of``    ``// a node contains node A``    ``int` `check_subtree[N + 1];` `    ``// DFS Call``    ``dfs(B, A, subtree_size,``        ``visited, check_subtree);` `    ``// Stores the difference between``    ``// total number of nodes and``    ``// subtree size of an immediate``    ``// child of Y lies between the``    ``// path from A to B``    ``int` `difference;` `    ``// Iterate over the adjacent nodes B``    ``for` `(``int` `v : G[B]) {` `        ``// If the node is in the path``        ``// from A to B``        ``if` `(check_subtree[v]) {` `            ``// Calculate the difference``            ``difference = N - subtree_size[v];` `            ``break``;``        ``}``    ``}` `    ``// Return the final answer``    ``return` `(N * (N - 1))``           ``- difference * (subtree_size[A]);``}` `// Driver Code``int32_t main()``{``    ``int` `N = 9;` `    ``int` `X = 5, Y = 3;` `    ``// Insert Edges``    ``addedge(0, 2);``    ``addedge(1, 2);``    ``addedge(2, 3);``    ``addedge(3, 4);``    ``addedge(4, 6);``    ``addedge(4, 5);``    ``addedge(5, 7);``    ``addedge(5, 8);` `    ``cout << numberOfPairs(N, Y, X);` `    ``return` `0;``}`

## Java

 `// Java Program to implement``// the above approach``import` `java.util.*;``class` `GFG{` `// Maximum number of nodes``static` `int` `NN = (``int``) 3e5;` `// Vector to store the tree``static` `Vector []G = ``new` `Vector[NN + ``1``];` `// Function to perform DFS Traversal``static` `int` `dfs(``int` `node, ``int` `A, ``int``[] subtree_size,``               ``int``[] visited, ``int``[] check_subtree)``{``    ``// Mark the node as visited``    ``visited[node] = ``1``;` `    ``// Initialize the subtree size``    ``// of each node as 1``    ``subtree_size[node] = ``1``;` `    ``// If the node is same as A``    ``if` `(node == A)``    ``{` `        ``// Mark check_subtree[node] as true``        ``check_subtree[node] = ``1``;``    ``}` `    ``// Otherwise``    ``else``        ``check_subtree[node] = ``0``;` `    ``// Iterate over the adjacent nodes``    ``for` `(``int` `v : G[node])``    ``{` `        ``// If the adjacent node``        ``// is not visited``        ``if` `(visited[v] == ``0``)``        ``{` `            ``// Update the size of the``            ``// subtree of current node``            ``subtree_size[node] += dfs(v, A, subtree_size,``                                      ``visited, check_subtree);` `            ``// Check if the subtree of``            ``// current node contains node A``            ``check_subtree[node] = check_subtree[node] |``                                    ``check_subtree[v];``        ``}``    ``}` `    ``// Return size of subtree of node``    ``return` `subtree_size[node];``}` `// Function to add edges to the tree``static` `void` `addedge(``int` `node1, ``int` `node2)``{``    ``G[node1].add(node2);``    ``G[node2].add(node1);``}` `// Function to calculate the number of``// possible paths``static` `int` `numberOfPairs(``int` `N, ``int` `B, ``int` `A)``{``    ``// Stores the size of subtree``    ``// of each node``    ``int` `[]subtree_size = ``new` `int``[N + ``1``];` `    ``// Stores which nodes are``    ``// visited``    ``int` `[]visited = ``new` `int``[N + ``1``];`  `    ``// Stores if the subtree of``    ``// a node contains node A``    ``int` `[]check_subtree = ``new` `int``[N + ``1``];` `    ``// DFS Call``    ``dfs(B, A, subtree_size,``        ``visited, check_subtree);` `    ``// Stores the difference between``    ``// total number of nodes and``    ``// subtree size of an immediate``    ``// child of Y lies between the``    ``// path from A to B``    ``int` `difference = ``0``;` `    ``// Iterate over the adjacent nodes B``    ``for` `(``int` `v : G[B])``    ``{` `        ``// If the node is in the path``        ``// from A to B``        ``if` `(check_subtree[v] > ``0``)``        ``{` `            ``// Calculate the difference``            ``difference = N - subtree_size[v];` `            ``break``;``        ``}``    ``}` `    ``// Return the final answer``    ``return` `(N * (N - ``1``)) -``              ``difference * (subtree_size[A]);``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``int` `N = ``9``;` `    ``int` `X = ``5``, Y = ``3``;``    ` `    ``for` `(``int` `i = ``0``; i < G.length; i++)``        ``G[i] = ``new` `Vector();``  ` `    ``// Insert Edges``    ``addedge(``0``, ``2``);``    ``addedge(``1``, ``2``);``    ``addedge(``2``, ``3``);``    ``addedge(``3``, ``4``);``    ``addedge(``4``, ``6``);``    ``addedge(``4``, ``5``);``    ``addedge(``5``, ``7``);``    ``addedge(``5``, ``8``);` `    ``System.out.print(numberOfPairs(N, Y, X));``}``}` `// This code is contributed by sapnasingh4991`

## Python3

 `# Python3 program to implement``# the above approach` `# Maximum number of nodes``NN ``=` `int``(``3e5``)` `# Vector to store the tree``G ``=` `[]``for` `i ``in` `range``(NN ``+` `1``):``    ``G.append([])` `# Function to perform DFS Traversal``def` `dfs(node, A, subtree_size,``        ``visited, check_subtree):` `    ``# Mark the node as visited``    ``visited[node] ``=` `True` `    ``# Initialize the subtree size``    ``# of each node as 1``    ``subtree_size[node] ``=` `1` `    ``# If the node is same as A``    ``if` `(node ``=``=` `A):` `        ``# Mark check_subtree[node] as true``        ``check_subtree[node] ``=` `True` `    ``# Otherwise``    ``else``:``        ``check_subtree[node] ``=` `False` `    ``# Iterate over the adjacent nodes``    ``for` `v ``in` `G[node]:` `        ``# If the adjacent node``        ``# is not visited``        ``if` `(``not` `visited[v]):` `            ``# Update the size of the``            ``# subtree of current node``            ``subtree_size[node] ``+``=` `dfs(v, A,``                                      ``subtree_size,``                                      ``visited,``                                      ``check_subtree)` `            ``# Check if the subtree of``            ``# current node contains node A``            ``check_subtree[node] ``=` `(check_subtree[node] |``                                   ``check_subtree[v])` `    ``# Return size of subtree of node``    ``return` `subtree_size[node]` `# Function to add edges to the tree``def` `addedge(node1, node2):` `    ``G[node1] ``+``=` `[node2]``    ``G[node2] ``+``=` `[node1]` `# Function to calculate the number of``# possible paths``def` `numberOfPairs(N, B, A):` `    ``# Stores the size of subtree``    ``# of each node``    ``subtree_size ``=` `[``0``] ``*` `(N ``+` `1``)` `    ``# Stores which nodes are``    ``# visited``    ``visited ``=` `[``0``] ``*` `(N ``+` `1``)` `    ``# Stores if the subtree of``    ``# a node contains node A``    ``check_subtree ``=` `[``0``] ``*` `(N ``+` `1``)` `    ``# DFS Call``    ``dfs(B, A, subtree_size,``        ``visited, check_subtree)` `    ``# Stores the difference between``    ``# total number of nodes and``    ``# subtree size of an immediate``    ``# child of Y lies between the``    ``# path from A to B``    ``difference ``=` `0` `    ``# Iterate over the adjacent nodes B``    ``for` `v ``in` `G[B]:` `        ``# If the node is in the path``        ``# from A to B``        ``if` `(check_subtree[v]):` `            ``# Calculate the difference``            ``difference ``=` `N ``-` `subtree_size[v]``            ``break` `    ``# Return the final answer``    ``return` `((N ``*` `(N ``-` `1``)) ``-``               ``difference ``*` `(subtree_size[A]))` `# Driver Code``N ``=` `9``X ``=` `5``Y ``=` `3` `# Insert Edges``addedge(``0``, ``2``)``addedge(``1``, ``2``)``addedge(``2``, ``3``)``addedge(``3``, ``4``)``addedge(``4``, ``6``)``addedge(``4``, ``5``)``addedge(``5``, ``7``)``addedge(``5``, ``8``)` `# Function call``print``(numberOfPairs(N, Y, X))` `# This code is contributed by Shivam Singh`

## C#

 `// C# Program to implement``// the above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG{` `// Maximum number of nodes``static` `int` `NN = (``int``) 3e5;` `// List to store the tree``static` `List<``int``> []G = ``new` `List<``int``>[NN + 1];` `// Function to perform DFS Traversal``static` `int` `dfs(``int` `node, ``int` `A, ``int``[] subtree_size,``               ``int``[] visited, ``int``[] check_subtree)``{``    ``// Mark the node as visited``    ``visited[node] = 1;` `    ``// Initialize the subtree size``    ``// of each node as 1``    ``subtree_size[node] = 1;` `    ``// If the node is same as A``    ``if` `(node == A)``    ``{` `        ``// Mark check_subtree[node] as true``        ``check_subtree[node] = 1;``    ``}` `    ``// Otherwise``    ``else``        ``check_subtree[node] = 0;` `    ``// Iterate over the adjacent nodes``    ``foreach` `(``int` `v ``in` `G[node])``    ``{` `        ``// If the adjacent node``        ``// is not visited``        ``if` `(visited[v] == 0)``        ``{` `            ``// Update the size of the``            ``// subtree of current node``            ``subtree_size[node] += dfs(v, A, subtree_size,``                                      ``visited, check_subtree);` `            ``// Check if the subtree of``            ``// current node contains node A``            ``check_subtree[node] = check_subtree[node] |``                                    ``check_subtree[v];``        ``}``    ``}` `    ``// Return size of subtree of node``    ``return` `subtree_size[node];``}` `// Function to add edges to the tree``static` `void` `addedge(``int` `node1, ``int` `node2)``{``    ``G[node1].Add(node2);``    ``G[node2].Add(node1);``}` `// Function to calculate the number of``// possible paths``static` `int` `numberOfPairs(``int` `N, ``int` `B, ``int` `A)``{``    ``// Stores the size of subtree``    ``// of each node``    ``int` `[]subtree_size = ``new` `int``[N + 1];` `    ``// Stores which nodes are``    ``// visited``    ``int` `[]visited = ``new` `int``[N + 1];`  `    ``// Stores if the subtree of``    ``// a node contains node A``    ``int` `[]check_subtree = ``new` `int``[N + 1];` `    ``// DFS Call``    ``dfs(B, A, subtree_size,``        ``visited, check_subtree);` `    ``// Stores the difference between``    ``// total number of nodes and``    ``// subtree size of an immediate``    ``// child of Y lies between the``    ``// path from A to B``    ``int` `difference = 0;` `    ``// Iterate over the adjacent nodes B``    ``foreach` `(``int` `v ``in` `G[B])``    ``{` `        ``// If the node is in the path``        ``// from A to B``        ``if` `(check_subtree[v] > 0)``        ``{` `            ``// Calculate the difference``            ``difference = N - subtree_size[v];` `            ``break``;``        ``}``    ``}` `    ``// Return the readonly answer``    ``return` `(N * (N - 1)) -``              ``difference * (subtree_size[A]);``}` `// Driver Code``public` `static` `void` `Main(String[] args)``{``    ``int` `N = 9;` `    ``int` `X = 5, Y = 3;``    ` `    ``for` `(``int` `i = 0; i < G.Length; i++)``        ``G[i] = ``new` `List<``int``>();``  ` `    ``// Insert Edges``    ``addedge(0, 2);``    ``addedge(1, 2);``    ``addedge(2, 3);``    ``addedge(3, 4);``    ``addedge(4, 6);``    ``addedge(4, 5);``    ``addedge(5, 7);``    ``addedge(5, 8);` `    ``Console.Write(numberOfPairs(N, Y, X));``}``}`  `// This code is contributed by sapnasingh4991`

## Javascript

 ``

Output:

`60`

Time Complexity: O(N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up