📌  相关文章
📜  无向图中所有连接组件的最大子数组总和

📅  最后修改于: 2021-05-06 18:18:00             🧑  作者: Mango

给定具有V个顶点和E个边的无向图,任务是在图的所有连接分量之间找到最大连续子数组和

例子:

方法:想法是使用深度优先搜索遍历来跟踪无向图中的连接组件,如本文所述。对于每个连接的组件,将根据本文所述的Kadane算法对数组进行分析,并计算最大连续子数组和。设置一个全局变量,该变量在每次迭代时都与局部和值进行比较以获得最终结果。

下面是上述方法的实现:

C++
// C++ implementation to find
// largest subarray sum among
// all connected components
 
#include 
using namespace std;
 
// Function to traverse the undirected
// graph using the Depth first traversal
void depthFirst(int v, vector graph[],
                vector& visited,
                vector& storeChain)
{
    // Marking the visited
    // vertex as true
    visited[v] = true;
 
    // Store the connected chain
    storeChain.push_back(v);
 
    for (auto i : graph[v]) {
        if (visited[i] == false) {
 
            // Recursive call to
            // the DFS algorithm
            depthFirst(i, graph,
                       visited, storeChain);
        }
    }
}
 
// Function to return maximum
// subarray sum of each connected
// component using Kadane's Algorithm
int subarraySum(int arr[], int n)
{
    int maxSubarraySum = arr[0];
    int currentMax = arr[0];
 
    // Following loop finds maximum
    // subarray sum based on Kadane's
    // algorithm
    for (int i = 1; i < n; i++) {
        currentMax = max(arr[i],
                         arr[i] + currentMax);
 
        // Global maximum subarray sum
        maxSubarraySum = max(maxSubarraySum,
                             currentMax);
    }
 
    // Returning the sum
    return maxSubarraySum;
}
 
// Function to find the maximum subarray
// sum among all connected components
void maxSubarraySum(
    vector graph[], int vertices,
    vector values)
{
    // Initializing boolean array
    // to mark visited vertices
    vector visited(1001, false);
 
    // maxSum stores the
    // maximum subarray sum
    int maxSum = INT_MIN;
 
    // Following loop invokes DFS algorithm
    for (int i = 1; i <= vertices; i++) {
        if (visited[i] == false) {
 
            // Variable to hold
            // temporary length
            int sizeChain;
 
            // Variable to hold temporary
            // maximum subarray sum values
            int tempSum;
 
            // Container to store each chain
            vector storeChain;
 
            // DFS algorithm
            depthFirst(i, graph, visited, storeChain);
 
            // Variable to hold each chain size
            sizeChain = storeChain.size();
 
            // Container to store values
            // of vertices of individual chains
            int chainValues[sizeChain + 1];
 
            // Storing the values of each chain
            for (int i = 0; i < sizeChain; i++) {
                int temp = values[storeChain[i] - 1];
                chainValues[i] = temp;
            }
 
            // Function call to find maximum
            // subarray sum of current connection
            tempSum = subarraySum(chainValues,
                                  sizeChain);
 
            // Conditional to store current
            // maximum subarray sum
            if (tempSum > maxSum) {
                maxSum = tempSum;
            }
        }
    }
 
    // Printing global maximum subarray sum
    cout << "Maximum subarray sum among all ";
    cout << "connected components = ";
    cout << maxSum;
}
 
// Driver code
int main()
{
    // Initializing graph in the
    // form of adjacency list
    vector graph[1001];
 
    // Defining the number
    // of edges and vertices
    int E, V;
    E = 4;
    V = 7;
 
    // Assigning the values for each
    // vertex of the undirected graph
    vector values;
    values.push_back(3);
    values.push_back(2);
    values.push_back(4);
    values.push_back(-2);
    values.push_back(0);
    values.push_back(-1);
    values.push_back(-5);
 
    // Constructing the undirected graph
    graph[1].push_back(2);
    graph[2].push_back(1);
    graph[3].push_back(4);
    graph[4].push_back(3);
    graph[4].push_back(5);
    graph[5].push_back(4);
    graph[6].push_back(7);
    graph[7].push_back(6);
 
    maxSubarraySum(graph, V, values);
    return 0;
}


Java
// Java implementation to find
// largest subarray sum among
// all connected components
import java.io.*;
import java.util.*;
 
class GFG{
 
// Function to traverse the undirected
// graph using the Depth first traversal
static void depthFirst(int v, List> graph,
                       boolean[] visited,
                       List storeChain)
{
  // Marking the visited
  // vertex as true
  visited[v] = true;
 
  // Store the connected chain
  storeChain.add(v);
 
  for (int i : graph.get(v))
  {
    if (visited[i] == false)
    {
      // Recursive call to
      // the DFS algorithm
      depthFirst(i, graph,
                 visited,
                 storeChain);
    }
  }
}
 
// Function to return maximum
// subarray sum of each connected
// component using Kadane's Algorithm
static int subarraySum(int arr[],
                       int n)
{
  int maxSubarraySum = arr[0];
  int currentMax = arr[0];
 
  // Following loop finds maximum
  // subarray sum based on Kadane's
  // algorithm
  for (int i = 1; i < n; i++)
  {
    currentMax = Math.max(arr[i], arr[i] +
                          currentMax);
 
    // Global maximum subarray sum
    maxSubarraySum = Math.max(maxSubarraySum,
                              currentMax);
  }
 
  // Returning the sum
  return maxSubarraySum;
}
 
// Function to find the maximum subarray
// sum among all connected components
static void maxSubarraySum(List> graph,
                           int vertices,
                           List values)
{
  // Initializing boolean array
  // to mark visited vertices
  boolean[] visited = new boolean[1001];
 
  // maxSum stores the
  // maximum subarray sum
  int maxSum = Integer.MIN_VALUE;
 
  // Following loop invokes DFS
  // algorithm
  for (int i = 1; i <= vertices; i++)
  {
    if (visited[i] == false)
    {
      // Variable to hold
      // temporary length
      int sizeChain;
 
      // Variable to hold temporary
      // maximum subarray sum values
      int tempSum;
 
      // Container to store each chain
      List storeChain =
           new ArrayList();
 
      // DFS algorithm
      depthFirst(i, graph,
                 visited, storeChain);
 
      // Variable to hold each
      // chain size
      sizeChain = storeChain.size();
 
      // Container to store values
      // of vertices of individual chains
      int[] chainValues =
            new int[sizeChain + 1];
 
      // Storing the values of each chain
      for (int j = 0; j < sizeChain; j++)
      {
        int temp = values.get(storeChain.get(j) - 1);
        chainValues[j] = temp;
      }
 
      // Function call to find maximum
      // subarray sum of current connection
      tempSum = subarraySum(chainValues,
                            sizeChain);
 
      // Conditional to store current
      // maximum subarray sum
      if (tempSum > maxSum)
      {
        maxSum = tempSum;
      }
    }
  }
 
  // Printing global maximum subarray sum
  System.out.print("Maximum subarray sum among all ");
  System.out.print("connected components = ");
  System.out.print(maxSum);
}
 
// Driver code
public static void main(String[] args)
{
  // Initializing graph in the
  // form of adjacency list
  List> graph =
       new ArrayList();
 
  for (int i = 0; i < 1001; i++)
    graph.add(new ArrayList());
 
  // Defining the number
  // of edges and vertices
  int E = 4, V = 7;
 
  // Assigning the values for each
  // vertex of the undirected graph
  List values =
       new ArrayList();
   
  values.add(3);
  values.add(2);
  values.add(4);
  values.add(-2);
  values.add(0);
  values.add(-1);
  values.add(-5);
 
  // Constructing the undirected
  // graph
  graph.get(1).add(2);
  graph.get(2).add(1);
  graph.get(3).add(4);
  graph.get(4).add(3);
  graph.get(4).add(5);
  graph.get(5).add(4);
  graph.get(6).add(7);
  graph.get(7).add(6);
 
  maxSubarraySum(graph, V, values);
}
}
 
// This code is contributed by jithin


Python3
# Python3 implementation to find
# largest subarray sum among
# all connected components
import sys
  
# Function to traverse
# the undirected graph
# using the Depth first
# traversal
def depthFirst(v, graph,
               visited,
               storeChain):
 
    # Marking the visited
    # vertex as true
    visited[v] = True;
  
    # Store the connected chain
    storeChain.append(v);
     
    for i in graph[v]:
        if (visited[i] == False):
  
            # Recursive call to
            # the DFS algorithm
            depthFirst(i, graph,
                       visited,
                       storeChain);       
  
# Function to return maximum
# subarray sum of each connected
# component using Kadane's Algorithm
def subarraySum(arr, n):
 
    maxSubarraySum = arr[0];
    currentMax = arr[0];
  
    # Following loop finds maximum
    # subarray sum based on Kadane's
    # algorithm
    for i in range(1, n):
        currentMax = max(arr[i],
                         arr[i] +
                         currentMax)
  
        # Global maximum subarray sum
        maxSubarraySum = max(maxSubarraySum,
                             currentMax);   
  
    # Returning the sum
    return maxSubarraySum;
  
# Function to find the
# maximum subarray sum
# among all connected components
def maxSubarraySum(graph,
                   vertices, values):
 
    # Initializing boolean array
    # to mark visited vertices
    visited = [False for i in range(1001)]
  
    # maxSum stores the
    # maximum subarray sum
    maxSum = -sys.maxsize;
  
    # Following loop invokes
    # DFS algorithm
    for i in range(1, vertices + 1):   
        if (visited[i] == False):
  
            # Variable to hold
            # temporary length
            sizeChain = 0
  
            # Variable to hold
            # temporary maximum
            # subarray sum values
            tempSum = 0;
  
            # Container to store
            # each chain
            storeChain = [];
  
            # DFS algorithm
            depthFirst(i, graph,
                       visited,
                       storeChain);
  
            # Variable to hold each
            # chain size
            sizeChain = len(storeChain)
  
            # Container to store values
            # of vertices of individual chains
            chainValues = [0 for i in range(sizeChain + 1)];
  
            # Storing the values of each chain
            for i in range(sizeChain):       
                temp = values[storeChain[i] - 1];
                chainValues[i] = temp;           
  
            # Function call to find maximum
            # subarray sum of current connection
            tempSum = subarraySum(chainValues,
                                  sizeChain);
  
            # Conditional to store current
            # maximum subarray sum
            if (tempSum > maxSum):
                maxSum = tempSum;           
  
    # Printing global maximum subarray sum
    print("Maximum subarray sum among all ",
           end = '');
    print("connected components = ",
           end = '')
    print(maxSum)
 
if __name__=="__main__":
     
    # Initializing graph in the
    # form of adjacency list
    graph = [[] for i in range(1001)]
  
    # Defining the number
    # of edges and vertices
    E = 4;
    V = 7;
  
    # Assigning the values
    # for each vertex of the
    # undirected graph
    values = [];
    values.append(3);
    values.append(2);
    values.append(4);
    values.append(-2);
    values.append(0);
    values.append(-1);
    values.append(-5);
  
    # Constructing the
    # undirected graph
    graph[1].append(2);
    graph[2].append(1);
    graph[3].append(4);
    graph[4].append(3);
    graph[4].append(5);
    graph[5].append(4);
    graph[6].append(7);
    graph[7].append(6);
  
    maxSubarraySum(graph, V, values);
     
# This code is contributed by rutvik_56


C#
// C# implementation to find
// largest subarray sum among
// all connected components
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG{
  
// Function to traverse the undirected
// graph using the Depth first traversal
static void depthFirst(int v, List> graph,
                       bool[] visited,
                       List storeChain)
{
   
  // Marking the visited
  // vertex as true
  visited[v] = true;
   
  // Store the connected chain
  storeChain.Add(v);
  
  foreach (int i in graph[v])
  {
    if (visited[i] == false)
    {
       
      // Recursive call to
      // the DFS algorithm
      depthFirst(i, graph,
                 visited,
                 storeChain);
    }
  }
}
  
// Function to return maximum
// subarray sum of each connected
// component using Kadane's Algorithm
static int subarraySum(int []arr,
                       int n)
{
  int maxSubarraySum = arr[0];
  int currentMax = arr[0];
   
  // Following loop finds maximum
  // subarray sum based on Kadane's
  // algorithm
  for(int i = 1; i < n; i++)
  {
    currentMax = Math.Max(arr[i], arr[i] +
                          currentMax);
     
    // Global maximum subarray sum
    maxSubarraySum = Math.Max(maxSubarraySum,
                              currentMax);
  }
   
  // Returning the sum
  return maxSubarraySum;
}
  
// Function to find the maximum subarray
// sum among all connected components
static void maxSubarraySum(List> graph,
                           int vertices,
                           List values)
{
   
  // Initializing boolean array
  // to mark visited vertices
  bool[] visited = new bool[1001];
  
  // maxSum stores the
  // maximum subarray sum
  int maxSum = -1000000;
  
  // Following loop invokes DFS
  // algorithm
  for(int i = 1; i <= vertices; i++)
  {
    if (visited[i] == false)
    {
       
      // Variable to hold
      // temporary length
      int sizeChain;
       
      // Variable to hold temporary
      // maximum subarray sum values
      int tempSum;
  
      // Container to store each chain
      List storeChain = new List();
       
      // DFS algorithm
      depthFirst(i, graph,
                 visited, storeChain);
  
      // Variable to hold each
      // chain size
      sizeChain = storeChain.Count;
  
      // Container to store values
      // of vertices of individual chains
      int[] chainValues = new int[sizeChain + 1];
  
      // Storing the values of each chain
      for(int j = 0; j < sizeChain; j++)
      {
        int temp = values[storeChain[j] - 1];
        chainValues[j] = temp;
      }
  
      // Function call to find maximum
      // subarray sum of current connection
      tempSum = subarraySum(chainValues,
                            sizeChain);
  
      // Conditional to store current
      // maximum subarray sum
      if (tempSum > maxSum)
      {
        maxSum = tempSum;
      }
    }
  }
   
  // Printing global maximum subarray sum
  Console.Write("Maximum subarray sum among all ");
  Console.Write("connected components = ");
  Console.Write(maxSum);
}
  
// Driver code
public static void Main(string[] args)
{
   
  // Initializing graph in the
  // form of adjacency list
  List> graph = new List>();
   
  for(int i = 0; i < 1001; i++)
    graph.Add(new List());
  
  // Defining the number
  // of edges and vertices
  int V = 7;
  
  // Assigning the values for each
  // vertex of the undirected graph
  List values = new List();
   
  values.Add(3);
  values.Add(2);
  values.Add(4);
  values.Add(-2);
  values.Add(0);
  values.Add(-1);
  values.Add(-5);
  
  // Constructing the undirected
  // graph
  graph[1].Add(2);
  graph[2].Add(1);
  graph[3].Add(4);
  graph[4].Add(3);
  graph[4].Add(5);
  graph[5].Add(4);
  graph[6].Add(7);
  graph[7].Add(6);
  
  maxSubarraySum(graph, V, values);
}
}
 
// This code is contributed by pratham76


输出
Maximum subarray sum among all connected components = 5

时间复杂度: O(V 2 )
DFS算法需要O(V + E)的时间来运行,其中V,E是无向图的顶点和边缘。此外,在每次迭代中找到最大连续子数组总和,该子数组总和需要额外的O(V)才能基于Kadane算法计算并返回结果。因此,总体复杂度为O(V 2 )