📜  给定非循环图每个深度的最小元素总和

📅  最后修改于: 2021-10-25 05:11:22             🧑  作者: Mango

给定一个具有V 个节点和E 条边的非循环图和一个源节点S ,任务是计算给定图中源节点S在每个级别的最小元素的总和。
例子:

方法:想法是使用DFS Traversal。以下是步骤:

  1. 初始化一个数组(比如arr[] )以存储每个级别的最小元素。
  2. 从具有可变深度(初始为0 )的给定源节点S开始 DFS 遍历。
  3. 更新数组arr[]中当前深度的最小值。
  4. 递归地递归子节点,增加前一次递归调用的深度值,以便相应深度处的最小值可以相应地更新。
  5. 在上述步骤之后,存储在arr[] 中的值的总和就是所需的总和。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to add an edge in a graph
void addEdge(vector adj[],
            int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}
 
// Variable to store depth of graph
int max_depth = 0;
 
// Function to know the depth of graph
void find_depth(vector adj[],
                vector& visited,
                int start, int depth)
{
    // Mark the node start as true
    visited[start] = true;
 
    // Update the maximum depth
    max_depth = max(max_depth, depth);
 
    // Recurr for the child node of
    // start node
    for (auto i : adj[start]) {
        if (!visited[i])
            find_depth(adj, visited,
                    i, depth + 1);
    }
}
 
// Function to calculate min value
// at every depth
void dfs(vector adj[], int start,
        vector& visited,
        vector& store_min_elements,
        int depth)
{
    // marking already visited
    // vertices as true
    visited[start] = true;
 
    // Store the min value for
    // every depth
    store_min_elements[depth]
        = min(store_min_elements[depth],
            start);
 
    // Traverse Child node of start node
    for (auto i : adj[start]) {
        if (!visited[i])
            dfs(adj, i, visited,
                store_min_elements,
                depth + 1);
    }
}
 
// Function to calculate the sum
void minSum_depth(vector adj[],
                int start,
                int total_nodes)
{
    vector visited(total_nodes,
                        false);
 
    // Calling function to know
    // the depth of graph
    find_depth(adj, visited,
            start, 0);
 
    // Set all value of visited
    // to false again
    fill(visited.begin(),
        visited.end(), false);
 
    // Declaring vector of
    // "max_depth + 1" size to
    // store min values at every
    // depth initialise vector
    // with max number
    vector store_min_elements(
        max_depth + 1, INT_MAX);
 
    // Calling dfs function for
    // calculation of min element
    // at every depth
    dfs(adj, start, visited,
        store_min_elements, 0);
 
    // Variable to store sum of
    // all min elements
    int min_sum = 0;
 
    // Calculation of minimum sum
    for (int i = 0;
        i < store_min_elements.size();
        i++) {
        min_sum += store_min_elements[i];
    }
 
    // Print the minimum sum
    cout << min_sum << endl;
}
 
// Driver Code
int main()
{
    // Given Nodes and start node
    int V = 7, start = 0;
 
    // Given graph
    vector adj[V];
    addEdge(adj, 0, 1);
    addEdge(adj, 0, 2);
    addEdge(adj, 0, 3);
    addEdge(adj, 1, 6);
    addEdge(adj, 2, 4);
    addEdge(adj, 3, 5);
 
    // Function Call
    minSum_depth(adj, start, V);
}


Java
// Java program for the above approach
import java.io.*;
import java.util.*;
 
class Graph{
     
public static int V;
 
// Variable to store depth of graph
public static int max_depth = 0;
private static LinkedList adj[];
 
@SuppressWarnings("unchecked")
Graph(int v)
{
    V = v;
    adj = new LinkedList[v];
    for(int i = 0; i < v; ++i)
        adj[i] = new LinkedList();
}
 
static void addEdge(int v, int w)
{
    adj[v].add(w);
}
 
static void find_depth(boolean visited[],
                       int start, int depth)
{
     
    // Mark the node start as true
    visited[start] = true;
 
    // Update the maximum depth
    max_depth = Math.max(max_depth, depth);
 
    // Recurr for the child node of
    // start node
    Iterator i = adj[start].listIterator();
    while (i.hasNext())
    {
        int n = i.next();
        if (!visited[n])
            find_depth(visited, n, depth + 1);
    }
}
 
// Function to calculate min value
// at every depth
static void dfs(int start, boolean visited[],
                int store_min_elements[],
                int depth)
{
     
    // Marking already visited
    // vertices as true
    visited[start] = true;
 
    // Store the min value for
    // every depth
    store_min_elements[depth] = Math.min(
        store_min_elements[depth], start);
 
    // Traverse Child node of start node
    Iterator i = adj[start].listIterator();
    while (i.hasNext())
    {
        int n = i.next();
        if (!visited[n])
            dfs(n, visited, store_min_elements,
                depth + 1);
    }
}
 
// Function to calculate the sum
static void minSum_depth(int start, int total_nodes)
{
    boolean visited[] = new boolean[total_nodes];
 
    // Calling function to know
    // the depth of graph
    find_depth(visited, start, 0);
 
    // Set all value of visited
    // to false again
    Arrays.fill(visited, false);
 
    // Declaring vector of
    // "max_depth + 1" size to
    // store min values at every
    // depth initialise vector
    // with max number
    int store_min_elements[] = new int[max_depth + 1];
    Arrays.fill(store_min_elements,
                Integer.MAX_VALUE);
                 
    // Calling dfs function for
    // calculation of min element
    // at every depth
    dfs(start, visited,
        store_min_elements, 0);
 
    // Variable to store sum of
    // all min elements
    int min_sum = 0;
 
    // Calculation of minimum sum
    for(int i = 0;
            i < store_min_elements.length;
            i++)
    {
        min_sum += store_min_elements[i];
    }
 
    // Print the minimum sum
    System.out.println(min_sum);
}
 
// Driver Code
public static void main(String args[])
{
     
    // Given Nodes and start node
    V = 7;
    int start = 0;
     
    Graph g = new Graph(V);
     
    // Given graph
    g.addEdge(0, 1);
    g.addEdge(0, 2);
    g.addEdge(0, 3);
    g.addEdge(1, 6);
    g.addEdge(2, 4);
    g.addEdge(3, 5);
 
    // Function call
    minSum_depth( start, V);
}
}
 
// This code is contributed by Stream_Cipher


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class Graph{
     
private static int V;
private static int start;
 
// Variable to store depth of graph
public static int max_depth = 0;
private static List[] adj;
 
Graph(int v)
{
    V = v;
    adj = new List[v];
    for(int i = 0; i < v; ++i)
        adj[i] = new List();
}
 
// Function to add an edge in a graph
void addEdge(int v, int w)
{
    adj[v].Add(w);
}
 
// Function to know the depth of graph
void find_depth(bool []visited,
                int start, int depth)
{
     
    // Mark the node start as true
    visited[start] = true;
 
    // Update the maximum depth
    max_depth = Math.Max(max_depth, depth);
 
    // Recurr for the child node of
    // start node
    List vList = adj[start];
    foreach(var n in vList)
    {
        if (!visited[n])
            find_depth(visited, n,
                       depth + 1);
    }
}
 
// Function to calculate min value
// at every depth
void dfs(int start, bool []visited,
         int []store_min_elements,
         int depth)
{
     
    // Marking already visited
    // vertices as true
    visited[start] = true;
 
    // Store the min value for
    // every depth
    store_min_elements[depth] = Math.Min(
        store_min_elements[depth], start);
 
    // Traverse Child node of start node
    List vList = adj[start];
    foreach(var n in vList)
    {
        if (!visited[n])
            dfs(n, visited,
                store_min_elements,
                depth + 1);
    }
}
 
// Function to calculate the sum
void minSum_depth(int start, int total_nodes)
{
    bool []visited = new bool[total_nodes];
 
    // Calling function to know
    // the depth of graph
    find_depth(visited, start, 0);
 
    // Set all value of visited
    // to false again
    for(int i = 0; i < visited.Length; i++)
    {
        visited[i] = false;
    }
 
    // Declaring vector of "max_depth + 1"
    // size to store min values at every
    // depth initialise vector with max number
    int []store_min_elements = new int [max_depth + 1];
    for(int i = 0;
            i < store_min_elements.Length;
            i++)
    {
        store_min_elements[i] = Int32.MaxValue;
    }
     
    // Calling dfs function for
    // calculation of min element
    // at every depth
    dfs(start, visited, store_min_elements, 0);
 
    // Variable to store sum of
    // all min elements
    int min_sum = 0;
     
    // Calculation of minimum sum
    for(int i = 0;
            i < store_min_elements.Length;
            i++)
    {
        min_sum += store_min_elements[i];
    }
 
    // Print the minimum sum
    Console.WriteLine(min_sum);
}
 
// Driver Code
public static void Main()
{
     
    // Given Nodes and start node
    V = 7;
    start = 0;
    Graph g = new Graph(V);
     
    // Given graph
    g.addEdge(0, 1);
    g.addEdge(0, 2);
    g.addEdge(0, 3);
    g.addEdge(1, 6);
    g.addEdge(2, 4);
    g.addEdge(3, 5);
 
    // Function call
    g.minSum_depth(start , V);
}
}
 
// This code is contributed by Stream_Cipher


Javascript


输出:
5

时间复杂度: O(V + E)
辅助空间: O(V)

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