Queries to find the count of shortest paths in a Tree that contains a given edge
Given a tree with N vertices numbered from 0 to N – 1, M edges, and Q queries of the form {U, V}, such that there is a direct edge between U and V in the tree. The task for each query is to find all possible shortest paths between any possible unordered pair of vertices from the given tree which contains the edge between the given pair of nodes.
Examples:
Input: N = 6, M[] ={{0, 1}, {0, 2}, {1, 3}, {3, 4}, {3, 5}}, queries[] = {{1, 3}, {0, 2}}
0
/ \
1 2
/
3
/ \
4 5
Output:
9
5
Explanation:
Query 1: The edge (1, 3) lies in the paths {1, 3), (1, 3, 4), (1, 3, 5), (0, 3), (0, 4), (0, 5), (2, 3), (2, 4) and (2, 5).
Query 2: The edge (0, 2) lies in the paths (2, 0), (2, 1), (2, 3), (2, 4) and (2, 5).
Input: N = 6, M[] ={{0, 1}, {0, 2}, {2, 3}, {1, 4}, {1, 5}}, queries[] = {{1, 5}, {0, 2}}
0
/ \
1 2
/ \ /
4 5 3
Output:
5
8
Approach: The problem can be solved based on the observation that for any query {U, V}, the shortest path between any pair of nodes in the tree will contain the given edge (U, V) if one of the nodes lies in the subtree of U and the other node lies in the remaining tree. Therefore, the required number of pairs will be:
Count of shortest paths containing (U, V) as an edge = subtreeSize(U) * (N – subtreeSize(V)).
Therefore, follow the steps below to solve the problem:
- Perform Depth First Search traversal on the tree starting from the root node.
- For each node, store the count of nodes in its subtree ( includes the node).
- Iterate over each query (U, V) and calculate:
min( subtreeSize(U), subtreeSize(V)) * ( N – min( subtreeSize(U), subtreeSize(V)) )
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int sz = 1e5;
vector< int > tree[sz];
int n;
bool vis[sz];
int subtreeSize[sz];
void addEdge( int a, int b)
{
tree[a].push_back(b);
tree[b].push_back(a);
}
void dfs( int x)
{
vis[x] = true ;
subtreeSize[x] = 1;
for ( auto i : tree[x]) {
if (!vis[i]) {
dfs(i);
subtreeSize[x]
+= subtreeSize[i];
}
}
}
void countPairs( int a, int b)
{
int sub = min(subtreeSize[a],
subtreeSize[b]);
cout << sub * (n - sub)
<< endl;
}
int main()
{
n = 6;
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 3);
addEdge(3, 4);
addEdge(3, 5);
dfs(0);
countPairs(1, 3);
countPairs(0, 2);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int sz = ( int ) 1e5;
static Vector<Integer> []tree = new Vector[sz];
static int n;
static boolean []vis = new boolean [sz];
static int []subtreeSize = new int [sz];
static void addEdge( int a, int b)
{
tree[a].add(b);
tree[b].add(a);
}
static void dfs( int x)
{
vis[x] = true ;
subtreeSize[x] = 1 ;
for ( int i : tree[x])
{
if (!vis[i])
{
dfs(i);
subtreeSize[x] += subtreeSize[i];
}
}
}
static void countPairs( int a, int b)
{
int sub = Math.min(subtreeSize[a],
subtreeSize[b]);
System.out.print(sub * (n - sub) + "\n" );
}
public static void main(String[] args)
{
n = 6 ;
for ( int i = 0 ; i < tree.length; i++)
tree[i] = new Vector<Integer>();
addEdge( 0 , 1 );
addEdge( 0 , 2 );
addEdge( 1 , 3 );
addEdge( 3 , 4 );
addEdge( 3 , 5 );
dfs( 0 );
countPairs( 1 , 3 );
countPairs( 0 , 2 );
}
}
|
Python3
sz = 100000
tree = [[] for i in range (sz)]
n = 0
vis = [ False ] * sz
subtreeSize = [ 0 for i in range (sz)]
def addEdge(a, b):
global tree
tree[a].append(b)
tree[b].append(a)
def dfs(x):
global vis
global subtreeSize
global tree
vis[x] = True
subtreeSize[x] = 1
for i in tree[x]:
if (vis[i] = = False ):
dfs(i)
subtreeSize[x] + = subtreeSize[i]
def countPairs(a, b):
global subtreeSize
sub = min (subtreeSize[a],
subtreeSize[b])
print (sub * (n - sub))
if __name__ = = '__main__' :
n = 6
addEdge( 0 , 1 )
addEdge( 0 , 2 )
addEdge( 1 , 3 )
addEdge( 3 , 4 )
addEdge( 3 , 5 )
dfs( 0 )
countPairs( 1 , 3 )
countPairs( 0 , 2 )
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int sz = ( int ) 1e5;
static List< int > []tree =
new List< int >[sz];
static int n;
static bool []vis = new bool [sz];
static int []subtreeSize = new int [sz];
static void addEdge( int a, int b)
{
tree[a].Add(b);
tree[b].Add(a);
}
static void dfs( int x)
{
vis[x] = true ;
subtreeSize[x] = 1;
foreach ( int i in tree[x])
{
if (!vis[i])
{
dfs(i);
subtreeSize[x] += subtreeSize[i];
}
}
}
static void countPairs( int a, int b)
{
int sub = Math.Min(subtreeSize[a],
subtreeSize[b]);
Console.Write(sub * (n - sub) + "\n" );
}
public static void Main(String[] args)
{
n = 6;
for ( int i = 0; i < tree.Length; i++)
tree[i] = new List< int >();
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 3);
addEdge(3, 4);
addEdge(3, 5);
dfs(0);
countPairs(1, 3);
countPairs(0, 2);
}
}
|
Javascript
<script>
var sz = 100005;
var tree = Array.from(Array(sz), ()=> Array())
var n;
var vis = Array(sz);
var subtreeSize = Array(sz);
function addEdge(a, b)
{
tree[a].push(b);
tree[b].push(a);
}
function dfs(x)
{
vis[x] = true ;
subtreeSize[x] = 1;
tree[x].forEach(i => {
if (!vis[i]) {
dfs(i);
subtreeSize[x]
+= subtreeSize[i];
}
});
}
function countPairs(a, b)
{
var sub = Math.min(subtreeSize[a],
subtreeSize[b]);
document.write( sub * (n - sub) + "<br>" );
}
n = 6;
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 3);
addEdge(3, 4);
addEdge(3, 5);
dfs(0);
countPairs(1, 3);
countPairs(0, 2);
</script>
|
Time Complexity: O(N + M + Q)
Auxiliary Space: O(N)
Last Updated :
26 May, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...