给定一个具有V个节点和E个边缘以及一个源节点S的非循环图,任务是从给定图中的源节点S计算每个级别上的最小元素之和。
例子:
Input: S = 0, Below is the given graph
Output: 5
Explanation:
There is only one node at depth 0 i.e. 0.
At depth 1 there are 3 nodes 1, 2, 3, and minimum of them is 1.
At depth 2 there are another 3 nodes i.e. 6, 4, 5, and a minimum of them is 4.
So the sum of minimum element at each depth is 0 + 1 + 4 = 5.
Input: S = 2, Below is the given graph
Output: 8
Explanation:
At depth 0 only 1 node exists i.e. 2.
At depth 1 minimum element is 0.
At depth 2 minimum element is 1.
At depth 3 minimum element is 5
So the sum of minimum element at each depth is 2 + 0 + 1 + 5 = 8.
方法:想法是使用DFS遍历。步骤如下:
- 初始化一个数组(例如arr [] )以在每个级别存储最小元素。
- 从给定的源节点S开始以可变深度(初始为0 )进行DFS遍历。
- 更新数组arr []中的当前深度的最小值。
- 通过从前一个递归调用增加depth的值来递归地为子节点递归,以便可以相应地更新对应深度处的最小值。
- 完成上述步骤后,存储在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
5
时间复杂度: O(V + E)
辅助空间: O(V)