📌  相关文章
📜  给定图中节点的最长递增序列的长度

📅  最后修改于: 2022-05-13 01:56:07.053000             🧑  作者: Mango

给定图中节点的最长递增序列的长度

给定一个图根,任务是找出图中最长递增序列的长度。

例子:

方法:给定的问题可以通过在图中的每个节点上使用深度优先搜索来解决。这个想法是使用递归并访问值小于当前节点的邻居节点,并在计算到当前节点的最长路径之前计算到邻居的最长路径。可以按照以下步骤解决问题:

  • 在根节点上应用深度优先搜索以访问并将所有节点存储在列表中
  • 使用递归在图的每个未访问节点上应用深度优先搜索,并使用哈希图将图映射的访问节点存储到到达该节点的最长路径
    • 在每个节点遍历邻居的 ArrayList 并在值小于当前节点的值的邻居节点上使用递归,并计算以它们结束的最长路径
    • 找到到邻居的最长路径的最大值并将其加 1 以计算到当前节点的最长路径
  • 返回所有最长路径的最大值

下面是上述方法的实现:

C++
// C++ code for the above approach
#include 
using namespace std;
 
class Node
{
public:
    vector neighbors;
    int val;
 
    // constructor
    Node(int v)
    {
 
        val = v;
        neighbors = {};
    }
};
 
// Depth first search function to add
// every node of the graph in a list
void dfs(
    Node *root,
    unordered_map &visited,
    vector &nodes)
{
 
    // If the current node is
    // already visited then return
    if (visited.find(root) != visited.end())
        return;
 
    // Mark the current node as visited
    visited[root] = 0;
 
    // Add the current node in the list
    nodes.push_back(root);
 
    // Iterate through all neighbors
    for (Node *n : root->neighbors)
    {
 
        // Visit the neighbors
        dfs(n, visited, nodes);
    }
}
// Depth first search function
// to calculate the longest path
// ending at every node
int findLongestPath(
    Node *root, unordered_map &visited)
{
 
    // If the current node is visited
    // then return its value
    if (visited[root] > 0)
        return visited[root];
 
    // Initialize a variable max to
    // calculate longest increasing path
    int maxi = 0;
 
    // Iterate through all neighbors
    for (Node *n : root->neighbors)
    {
 
        // If neighbor's value is less
        // than current node's value then
        // find longest path ending up to
        // the neighbor
        if (n->val < root->val)
        {
 
            // Update max
            maxi = max(
                maxi,
                findLongestPath(n, visited));
        }
    }
 
    // Store the value in the hashmap
    visited[root] = maxi + 1;
 
    // Return the longest increasing
    // path ending on root
    return maxi + 1;
}
// Function to find the longest
// increasing path in a graph
int longestIncPath(Node *root)
{
 
    // Base case
    if (root == NULL)
        return 0;
 
    // Initialize a variable max
    // to calculate longest path
    int maxi = 1;
 
    // Initialize a HashMap to
    // store the visited nodes
    unordered_map visited;
 
    // List to store all the
    // nodes in a graph
    vector nodes;
 
    // Apply DFS on the graph
    // add all the nodes in a list
    dfs(root, visited, nodes);
 
    // Iterate through the list of nodes
    for (int i = 0; i < nodes.size(); i++)
    {
 
        Node *curr = nodes[i];
 
        // Current node is not already visited
        if (visited[curr] == 0)
        {
 
            // Apply DFS to find the
            // longest path ending on
            // the current node
            findLongestPath(curr, visited);
        }
 
        // Update max by comparing it
        // with the longest path ending
        // on the current node
        maxi = max(
            maxi, visited[curr]);
    }
 
    // Return the answer
    return maxi;
}
 
// Driver code
int main()
{
 
    // Initialize the graph
    Node *seven = new Node(7);
    Node *five = new Node(5);
    Node *four = new Node(4);
    Node *sevTeen = new Node(17);
    Node *one = new Node(1);
    Node *two = new Node(2);
    Node *six = new Node(6);
    Node *eight = new Node(8);
    Node *eleven = new Node(11);
    Node *twelve = new Node(12);
    one->neighbors.push_back(two);
    eleven->neighbors.push_back(two);
    two->neighbors.push_back(one);
    two->neighbors.push_back(eleven);
    two->neighbors.push_back(five);
    eight->neighbors.push_back(twelve);
    eight->neighbors.push_back(six);
    eight->neighbors.push_back(four);
    four->neighbors.push_back(eight);
    four->neighbors.push_back(seven);
    twelve->neighbors.push_back(eight);
    six->neighbors.push_back(five);
    six->neighbors.push_back(eight);
    five->neighbors.push_back(two);
    five->neighbors.push_back(seven);
    five->neighbors.push_back(six);
    seven->neighbors.push_back(five);
    seven->neighbors.push_back(four);
    seven->neighbors.push_back(sevTeen);
    sevTeen->neighbors.push_back(seven);
 
    // Call the function
    // and print the result
    cout << (longestIncPath(seven));
    return 0;
}
 
// This code is contributed by Potta Lokesh


Java
// Java implementation for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    static class Node {
 
        List neighbors;
        int val;
 
        // constructor
        public Node(int val)
        {
 
            this.val = val;
            neighbors = new ArrayList<>();
        }
    }
 
    // Function to find the longest
    // increasing path in a graph
    public static int longestIncPath(Node root)
    {
 
        // Base case
        if (root == null)
            return 0;
 
        // Initialize a variable max
        // to calculate longest path
        int max = 1;
 
        // Initialize a HashMap to
        // store the visited nodes
        Map visited
            = new HashMap<>();
 
        // List to store all the
        // nodes in a graph
        List nodes = new ArrayList<>();
 
        // Apply DFS on the graph
        // add all the nodes in a list
        dfs(root, visited, nodes);
 
        // Iterate through the list of nodes
        for (int i = 0; i < nodes.size(); i++) {
 
            Node curr = nodes.get(i);
 
            // Current node is not already visited
            if (visited.get(curr) == 0) {
 
                // Apply DFS to find the
                // longest path ending on
                // the current node
                findLongestPath(curr, visited);
            }
 
            // Update max by comparing it
            // with the longest path ending
            // on the current node
            max = Math.max(
                max, visited.get(curr));
        }
 
        // Return the answer
        return max;
    }
 
    // Depth first search function
    // to calculate the longest path
    // ending at every node
    public static int findLongestPath(
        Node root, Map visited)
    {
 
        // If the current node is visited
        // then return its value
        if (visited.get(root) > 0)
            return visited.get(root);
 
        // Initialize a variable max to
        // calculate longest increasing path
        int max = 0;
 
        // Iterate through all neighbors
        for (Node n : root.neighbors) {
 
            // If neighbor's value is less
            // than current node's value then
            // find longest path ending up to
            // the neighbor
            if (n.val < root.val) {
 
                // Update max
                max = Math.max(
                    max,
                    findLongestPath(n, visited));
            }
        }
 
        // Store the value in the hashmap
        visited.put(root, max + 1);
 
        // Return the longest increasing
        // path ending on root
        return max + 1;
    }
 
    // Depth first search function to add
    // every node of the graph in a list
    public static void dfs(
        Node root,
        Map visited,
        List nodes)
    {
 
        // If the current node is
        // already visited then return
        if (visited.containsKey(root))
            return;
 
        // Mark the current node as visited
        visited.put(root, 0);
 
        // Add the current node in the list
        nodes.add(root);
 
        // Iterate through all neighbors
        for (Node n : root.neighbors) {
 
            // Visit the neighbors
            dfs(n, visited, nodes);
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        // Initialize the graph
        Node seven = new Node(7);
        Node five = new Node(5);
        Node four = new Node(4);
        Node sevTeen = new Node(17);
        Node one = new Node(1);
        Node two = new Node(2);
        Node six = new Node(6);
        Node eight = new Node(8);
        Node eleven = new Node(11);
        Node twelve = new Node(12);
        one.neighbors.add(two);
        eleven.neighbors.add(two);
        two.neighbors.add(one);
        two.neighbors.add(eleven);
        two.neighbors.add(five);
        eight.neighbors.add(twelve);
        eight.neighbors.add(six);
        eight.neighbors.add(four);
        four.neighbors.add(eight);
        four.neighbors.add(seven);
        twelve.neighbors.add(eight);
        six.neighbors.add(five);
        six.neighbors.add(eight);
        five.neighbors.add(two);
        five.neighbors.add(seven);
        five.neighbors.add(six);
        seven.neighbors.add(five);
        seven.neighbors.add(four);
        seven.neighbors.add(sevTeen);
        sevTeen.neighbors.add(seven);
 
        // Call the function
        // and print the result
        System.out.println(
            longestIncPath(seven));
    }
}


C#
// C# implementation for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
    class Node {
 
        public List neighbors;
        public int val;
 
        // constructor
        public Node(int val)
        {
 
            this.val = val;
            neighbors = new List();
        }
    }
 
    // Function to find the longest
    // increasing path in a graph
    static int longestIncPath(Node root)
    {
 
        // Base case
        if (root == null)
            return 0;
 
        // Initialize a variable max
        // to calculate longest path
        int max = 1;
 
        // Initialize a Dictionary to
        // store the visited nodes
        Dictionary visited
            = new Dictionary();
 
        // List to store all the
        // nodes in a graph
        List nodes = new List();
 
        // Apply DFS on the graph
        // add all the nodes in a list
        dfs(root, visited, nodes);
 
        // Iterate through the list of nodes
        for (int i = 0; i < nodes.Count; i++) {
 
            Node curr = nodes[i];
 
            // Current node is not already visited
            if (visited[curr] == 0) {
 
                // Apply DFS to find the
                // longest path ending on
                // the current node
                findlongestPath(curr, visited);
            }
 
            // Update max by comparing it
            // with the longest path ending
            // on the current node
            max = Math.Max(
                max, visited[curr]);
        }
 
        // Return the answer
        return max;
    }
 
    // Depth first search function
    // to calculate the longest path
    // ending at every node
    static int findlongestPath(
        Node root, Dictionary visited)
    {
 
        // If the current node is visited
        // then return its value
        if (visited[root] > 0)
            return visited[root];
 
        // Initialize a variable max to
        // calculate longest increasing path
        int max = 0;
 
        // Iterate through all neighbors
        foreach (Node n in root.neighbors) {
 
            // If neighbor's value is less
            // than current node's value then
            // find longest path ending up to
            // the neighbor
            if (n.val < root.val) {
 
                // Update max
                max = Math.Max(
                    max,
                    findlongestPath(n, visited));
            }
        }
 
        // Store the value in the hashmap
        if(visited.ContainsKey(root))
            visited[root] = max + 1;
        else
            visited.Add(root, max + 1);
 
        // Return the longest increasing
        // path ending on root
        return max + 1;
    }
 
    // Depth first search function to add
    // every node of the graph in a list
    static void dfs(
        Node root,
        Dictionary visited,
        List nodes)
    {
 
        // If the current node is
        // already visited then return
        if (visited.ContainsKey(root))
            return;
 
        // Mark the current node as visited
        visited.Add(root, 0);
 
        // Add the current node in the list
        nodes.Add(root);
 
        // Iterate through all neighbors
        foreach (Node n in root.neighbors) {
 
            // Visit the neighbors
            dfs(n, visited, nodes);
        }
    }
 
    // Driver code
    public static void Main(String[] args)
    {
 
        // Initialize the graph
        Node seven = new Node(7);
        Node five = new Node(5);
        Node four = new Node(4);
        Node sevTeen = new Node(17);
        Node one = new Node(1);
        Node two = new Node(2);
        Node six = new Node(6);
        Node eight = new Node(8);
        Node eleven = new Node(11);
        Node twelve = new Node(12);
        one.neighbors.Add(two);
        eleven.neighbors.Add(two);
        two.neighbors.Add(one);
        two.neighbors.Add(eleven);
        two.neighbors.Add(five);
        eight.neighbors.Add(twelve);
        eight.neighbors.Add(six);
        eight.neighbors.Add(four);
        four.neighbors.Add(eight);
        four.neighbors.Add(seven);
        twelve.neighbors.Add(eight);
        six.neighbors.Add(five);
        six.neighbors.Add(eight);
        five.neighbors.Add(two);
        five.neighbors.Add(seven);
        five.neighbors.Add(six);
        seven.neighbors.Add(five);
        seven.neighbors.Add(four);
        seven.neighbors.Add(sevTeen);
        sevTeen.neighbors.Add(seven);
 
        // Call the function
        // and print the result
        Console.WriteLine(
            longestIncPath(seven));
    }
}
 
// This code is contributed by 29AjayKumar


Javascript


输出
6

时间复杂度: O(V + E),其中 V 是顶点数,E 是边数
辅助空间: O(V)