📌  相关文章
📜  计算每条边出现在给定树的所有可能路径中的次数

📅  最后修改于: 2021-09-08 13:33:36             🧑  作者: Mango

给定一个由N 个节点和(N – 1) 条边组成的形式的无向连通图,每条边的任务是计算它在树中所有可能路径上出现的次数。

例子:

朴素方法:最简单的方法是从给定图中的每个节点生成所有可能的路径,并通过 HashMap 存储这些路径中出现的边数。最后,打印每条边的频率。
时间复杂度: O(N 2 )
辅助空间: O(N)

高效的方法:要优化上述方法,需要进行以下观察:

请按照以下步骤解决问题:

  • 在任何随机顶点处根树,比如 1。
  • 在根执行 DFS。使用 DFS 计算连接到边的子树大小。
  • 连接到子树的每条边的频率是(subtree size) * (N – subtree size)
  • 将上面为每个节点计算的值存储在一个 HashMap 中。最后,完成树的遍历后,遍历HashMap打印结果。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
 
// Number of nodes
int N;
 
// Structure of a Node
struct Node {
    int node;
    int edgeLabel;
};
 
// Adjacency List to
// represent the Tree
vector adj[100005];
 
// Stores the frequencies
// of every edge
vector freq;
 
// Function to perform DFS
int dfs(int u = 1, int p = 1)
{
    // Add the current node to
    // size of subtree rooted at u
    int sz = 1;
 
    // Iterate over its childern
    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 nodes
void 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 paths
void printFrequencies()
{
 
    // Stores the frequency
    // of all the edges
    freq = vector(N);
 
    // Perform DFS
    dfs();
 
    for (int i = 1; i < N; i++) {
        cout << freq[i] << " ";
    }
}
 
// Driver Code
int main()
{
    N = 4;
    addEdge(1, 2, 1);
    addEdge(2, 3, 2);
    addEdge(3, 4, 3);
 
    printFrequencies();
 
    return 0;
}


Java
// Java Program to implement
// the above approach
import java.util.*;
class GFG{
 
// Number of nodes
static int N;
 
// Structure of a Node
static class Node
{
    int node;
    int edgeLabel;
    public Node(int node, int edgeLabel)
    {
        super();
        this.node = node;
        this.edgeLabel = edgeLabel;
    }
};
 
// Adjacency List to
// represent the Tree
static Vector []adj = new Vector[100005];
 
// Stores the frequencies
// of every edge
static int []freq;
 
// Function to perform DFS
static int dfs(int u , int p)
{ 
    // Add the current node to
    // size of subtree rooted at u
    int sz = 1;
 
    // Iterate over its childern
    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 nodes
static 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 paths
static 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 Code
public static void main(String[] args)
{
    N = 4;
    for (int i = 0; i < adj.length; i++)
        adj[i] = new Vector();
    addEdge(1, 2, 1);
    addEdge(2, 3, 2);
    addEdge(3, 4, 3);
   
    printFrequencies();
}
}
 
// This code is contributed by shikhasingrajput


Python3
# Python3 program to implement
# the above approach
 
# Number of nodes
N = 4
 
# Structure of a Node
class Node:
     
    def __init__(self, v, label):
         
        self.node = v
        self.edgeLabel = label
         
# Adjacency list to
# represent the Tree
adj = []
for i in range(100005):
    adj.append([])
 
# Stores the frequencies
# of each edge
freq = [0] * N
 
# Function to perform DFS
def dfs(u = 1, p = 1):
     
    global N
     
    # Add the current node to
    # size of subtree rooted at u
    sz = 1
     
    # Iterate over its childern
    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 nodes
def 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 paths
def printFrequencies():
     
    # Stores the frequency
    # of all the edges
    global N
     
    # Perform DFS
    dfs()
     
    for i in range(1, N):
        print(freq[i], end = " ")
     
# Driver code
N = 4
addEdge(1, 2, 1)
addEdge(2, 3, 2)
addEdge(3, 4, 3)
 
printFrequencies()
     
# This code is contributed by Stuti Pathak


C#
// C# Program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Number of nodes
static int N;
 
// Structure of a Node
public 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 Tree
static List []adj =
       new List[100005];
 
// Stores the frequencies
// of every edge
static int []freq;
 
// Function to perform DFS
static int dfs(int u, int p)
{ 
    // Add the current node to
    // size of subtree rooted at u
    int sz = 1;
 
    // Iterate over its childern
    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 nodes
static 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 paths
static 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 Code
public static void Main(String[] args)
{
  N = 4;
  for (int i = 0; i < adj.Length; i++)
    adj[i] = new List();
  addEdge(1, 2, 1);
  addEdge(2, 3, 2);
  addEdge(3, 4, 3);
  printFrequencies();
}
}
 
// This code is contributed by gauravrajput1


Javascript


输出:
3 4 3

时间复杂度: O(N)
辅助空间:O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程