Count number of times each Edge appears in all possible paths of a given Tree

07 Sep, 2021
Given an Undirected Connected Graph in the form of a tree consisting of N nodes and (N – 1) edges, the task for each edge is to count the number of times it appears across all possible paths in the Tree.
Examples:
Input:
Output: 3 4 3 Explanation: All possible paths of a given tree are {(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)} Edge 1 occurs in the paths {(1, 2), (1, 3), (1, 4)}. Therefore, the frequency of the edge is 3. Edge 2 occurs in the paths {(1, 3), (1, 4), (2, 3), (2, 4)}. Therefore, the frequency of the edge is 4. Edge 3 occurs in the paths {(1, 4), (2, 4), (3, 4)}. Therefore, the frequency of the edge is 3. 
Input:
Output: 4 6 4 4 Explanation: Edge 1 occurs in the paths {(1, 2), (1, 3), (1, 4), (1, 5)}. Therefore, the frequency of the edge is 4 Edge 2 occurs in the paths {(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5)}. Therefore, the frequency of the edge is 6 Edge 3 occurs in the paths {(1, 4), (2, 4), (3, 4), (4, 5)}. Therefore, the frequency of the edge is 4 Edge 4 occurs in the paths {(1, 5), (2, 5), (3, 5), (4, 5)}. Therefore, the frequency of the edge is 4  
Naive Approach: The simplest approach is to generate all possible paths from each node of the given graph and store the count of edges occurring in these paths by a HashMap. Finally, print the frequencies of each edge. 
Time Complexity: O(N2) Auxiliary Space: O(N) 
Efficient Approach: To optimize the above approach, the following observation needs to be made:
The green-colored edge will appear in all the paths that connect any vertex from the subtree on its left to any vertex from the subtree on its right. Therefore, the number of paths in which the edge occurs = Product of the count of nodes in the two subtrees = 5 * 3 = 15.
Follow the steps below in order to solve the problem:  
Root the tree at any random vertex, say 1.
Perform DFS at Root. Using DFS calculate the subtree size connected to the edges.
The frequency of each edge connected to subtree is (subtree size) * (N – subtree size).
Store the value calculated above for each node in a HashMap. Finally, after complete the traversal of the tree, traverse the HashMap to print the result.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ Program to implement// the above approach#include <bits/stdc++.h>using namespace std; // Number of nodesint N; // Structure of a Nodestruct Node {    int node;    int edgeLabel;}; // Adjacency List to// represent the Treevector<Node> adj[100005]; // Stores the frequencies// of every edgevector<int> freq; // Function to perform DFSint dfs(int u = 1, int p = 1){    // Add the current node to    // size of subtree rooted at u    int sz = 1;     // Iterate over its children    for (auto a : adj[u]) {         // Check if child is not parent        if (a.node != p) {             // Get the subtree size            // for the child            int val = dfs(a.node, u);             // Set the frequency            // of the current edge            freq[a.edgeLabel]                = val * (N - val);             // Add the subtree size            // to itself            sz += val;        }    }     // Return the subtree size    return sz;} // Function to add edge between nodesvoid addEdge(int u, int v, int label){    adj[u].push_back({ v, label });    adj[v].push_back({ u, label });} // Function to print the frequencies// of each edge in all possible pathsvoid printFrequencies(){     // Stores the frequency    // of all the edges    freq = vector<int>(N);     // Perform DFS    dfs();     for (int i = 1; i < N; i++) {        cout << freq[i] << " ";    }} // Driver Codeint main(){    N = 4;    addEdge(1, 2, 1);    addEdge(2, 3, 2);    addEdge(3, 4, 3);     printFrequencies();     return 0;}
// Java Program to implement// the above approachimport java.util.*;class GFG{ // Number of nodesstatic int N; // Structure of a Nodestatic class Node{    int node;    int edgeLabel;    public Node(int node, int edgeLabel)    {        super();        this.node = node;        this.edgeLabel = edgeLabel;    }}; // Adjacency List to// represent the Treestatic Vector<Node> []adj = new Vector[100005]; // Stores the frequencies// of every edgestatic int []freq; // Function to perform DFSstatic int dfs(int u , int p){     // Add the current node to    // size of subtree rooted at u    int sz = 1;     // Iterate over its children    for (Node a : adj[u])    {        // Check if child is not parent        if (a.node != p)        {            // Get the subtree size            // for the child            int val = dfs(a.node, u);             // Set the frequency            // of the current edge            freq[a.edgeLabel] = val * (N - val);             // Add the subtree size            // to itself            sz += val;        }    }     // Return the subtree size    return sz;} // Function to add edge between nodesstatic void addEdge(int u, int v, int label){    adj[u].add(new Node( v, label ));    adj[v].add(new Node( u, label));} // Function to print the frequencies// of each edge in all possible pathsstatic void printFrequencies(){     // Stores the frequency    // of all the edges    freq = new int[N];     // Perform DFS    dfs(1, 1);     for (int i = 1; i < N; i++)    {        System.out.print(freq[i] + " ");    }} // Driver Codepublic static void main(String[] args){    N = 4;    for (int i = 0; i < adj.length; i++)        adj[i] = new Vector<Node>();    addEdge(1, 2, 1);    addEdge(2, 3, 2);    addEdge(3, 4, 3);       printFrequencies();}} // This code is contributed by shikhasingrajput
# Python3 program to implement# the above approach # Number of nodesN = 4 # Structure of a Nodeclass Node:         def __init__(self, v, label):                 self.node = v        self.edgeLabel = label         # Adjacency list to# represent the Treeadj = []for i in range(100005):    adj.append([]) # Stores the frequencies# of each edgefreq = [0] * N # Function to perform DFSdef dfs(u = 1, p = 1):         global N         # Add the current node to    # size of subtree rooted at u    sz = 1         # Iterate over its children    for a in adj[u]:                 # Check if child is not parent        if a.node != p:                         # Get the subtree size            # for the child            val = dfs(a.node, u)                         # Set the frequency            # of the current edge            freq[a.edgeLabel] = val * (N - val)                         # Add the subtree size            # to itself            sz += val                 # Return the subtree size    return sz # Function to add edge between nodesdef addEdge(u, v, label):         adj[u].append(Node(v, label))    adj[v].append(Node(u, label))     # Function to print the frequencies# of each edge in all possible pathsdef printFrequencies():         # Stores the frequency    # of all the edges    global N         # Perform DFS    dfs()         for i in range(1, N):        print(freq[i], end = " ")     # Driver codeN = 4addEdge(1, 2, 1)addEdge(2, 3, 2)addEdge(3, 4, 3) printFrequencies()     # This code is contributed by Stuti Pathak
// C# Program to implement// the above approachusing System;using System.Collections.Generic;class GFG{ // Number of nodesstatic int N; // Structure of a Nodepublic class Node{  public int node;  public int edgeLabel;  public Node(int node,              int edgeLabel)  {    this.node = node;    this.edgeLabel = edgeLabel;  }}; // Adjacency List to// represent the Treestatic List<Node> []adj =       new List<Node>[100005]; // Stores the frequencies// of every edgestatic int []freq; // Function to perform DFSstatic int dfs(int u, int p){     // Add the current node to    // size of subtree rooted at u    int sz = 1;     // Iterate over its children    foreach (Node a in adj[u])    {        // Check if child is not parent        if (a.node != p)        {            // Get the subtree size            // for the child            int val = dfs(a.node, u);             // Set the frequency            // of the current edge            freq[a.edgeLabel] = val * (N - val);             // Add the subtree size            // to itself            sz += val;        }    }     // Return the subtree size    return sz;} // Function to add edge between nodesstatic void addEdge(int u, int v,                    int label){  adj[u].Add(new Node(v, label));  adj[v].Add(new Node(u, label));} // Function to print the frequencies// of each edge in all possible pathsstatic void printFrequencies(){  // Stores the frequency  // of all the edges  freq = new int[N];   // Perform DFS  dfs(1, 1);   for (int i = 1; i < N; i++)  {    Console.Write(freq[i] + " ");  }} // Driver Codepublic static void Main(String[] args){  N = 4;  for (int i = 0; i < adj.Length; i++)    adj[i] = new List<Node>();  addEdge(1, 2, 1);  addEdge(2, 3, 2);  addEdge(3, 4, 3);  printFrequencies();}} // This code is contributed by gauravrajput1
<script>    // Javascript Program to implement the above approach         // Number of nodes    let N;     // Structure of a Node    class Node    {        constructor(node, edgeLabel) {           this.node = node;           this.edgeLabel = edgeLabel;        }    }     // Adjacency List to    // represent the Tree    let adj = new Array(100005);     // Stores the frequencies    // of every edge    let freq;     // Function to perform DFS    function dfs(u, p)    {        // Add the current node to        // size of subtree rooted at u        let sz = 1;         // Iterate over its children        for (let a = 0; a < adj[u].length; a++)        {            // Check if child is not parent            if (adj[u][a].node != p)            {                // Get the subtree size                // for the child                let val = dfs(adj[u][a].node, u);                 // Set the frequency                // of the current edge                freq[adj[u][a].edgeLabel] = val * (N - val);                 // Add the subtree size                // to itself                sz += val;            }        }         // Return the subtree size        return sz;    }     // Function to add edge between nodes    function addEdge(u, v, label)    {        adj[u].push(new Node( v, label ));        adj[v].push(new Node( u, label));    }     // Function to print the frequencies    // of each edge in all possible paths    function printFrequencies()    {         // Stores the frequency        // of all the edges        freq = new Array(N);         // Perform DFS        dfs(1, 1);         for (let i = 1; i < N; i++)        {            document.write(freq[i] + " ");        }    }         N = 4;    for (let i = 0; i < adj.length; i++)      adj[i] = [];    addEdge(1, 2, 1);    addEdge(2, 3, 2);    addEdge(3, 4, 3);    printFrequencies(); </script>
3 4 3
 
Time Complexity: O(N) Auxiliary Space: O(N) 
stutipathak31jan
shikhasingrajput
GauravRajput1
divyesh072019
surindertarika1234
DFS
frequency-counting
Data Structures
Graph
Hash
Tree
Data Structures
Hash
DFS
Graph
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.