📜  要添加到图中以满足给定条件的最小边数

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

鉴于由N图中的节点编号为0N – 1和对{A,B}的形式m条边中,任务是找到边缘的最小数量的要被添加到所述图形,使得如果存在一个从任何节点a到节点b 的路径,那么也应该有从节点a到节点[ a + 1, a + 2, a + 3, …, b – 1] 的路径。

例子:

方法:
这个想法是使用不相交集或联合查找。不相交集中的每个组件都应该有连续的节点。这可以通过维护maximum_node[]minimum_node[]数组来分别存储每个组件中节点的最大值和最小值来完成。请按照以下步骤解决问题:

  • 为不相交集合并创建一个结构。
  • 答案初始化为 0 并遍历图中的所有节点以获取当前节点的组件。
  • 如果未访问该组件,则将其标记为已访问。
  • 现在,从该组件的最小值到最大值进行迭代,并检查节点是否与当前节点在同一组件中,并将它们组合成一个组件并将答案增加1
  • 最后,打印答案

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
#include 
#define MOD 1000000007
 
#define int long long int
using namespace std;
 
// Disjoint Set Union
struct dsu {
 
    // Stores the parent
    // of each node
    vector parent;
 
    // Storing maximum value
    // in each component
    vector maximum_node;
 
    // Stores the minimum value
    // in each component
    vector minimum_node;
 
    // Stores the visited nodes
    vector visited;
 
    // Function to initialize the
    // values in vectors
    void init(int n)
    {
        // Initialize the size of
        // vectors as n
        parent.resize(n);
        maximum_node.resize(n);
        minimum_node.resize(n);
        visited.resize(n);
 
        for (int i = 0; i < n; i++) {
 
            // Initially every component
            // has only one node
            parent[i] = i;
            maximum_node[i] = i;
            minimum_node[i] = i;
 
            // Mark unvisited
            visited[i] = 0;
        }
    }
 
    // Function to get identifier node
    // (superparent) for each component
    int getsuperparent(int x)
    {
 
        // If parent of a node is that
        // node itself then the node is
        // superparent of that component
        return x == parent[x]
                   ? x
                   : parent[x]
                     = getsuperparent(parent[x]);
    }
 
    // Function to perform union of two
    // different components
    void unite(int x, int y)
    {
 
        int superparent_x = getsuperparent(x);
        int superparent_y = getsuperparent(y);
 
        // Set superparent of y as the
        // parent of superparent of x
        parent[superparent_x] = superparent_y;
 
        // Update the maximum node
        // in the component containing y
        maximum_node[superparent_y]
            = max(maximum_node[superparent_y],
                  maximum_node[superparent_x]);
 
        // Update the minimum node
        // in the component containing y
        minimum_node[superparent_y]
            = min(minimum_node[superparent_y],
                  minimum_node[superparent_x]);
    }
} G;
 
// Function to find the minimum number
// of edges to be added to the Graph
int minimumEdgesToBeAdded(int n)
{
    // Stores the answer
    int answer = 0;
 
    // Iterate over all nodes
    for (int i = 0; i < n; i++) {
 
        // Get the superparent of
        // the current node
        int temp = G.getsuperparent(i);
 
        // If the node is not visited
        if (!G.visited[temp]) {
 
            // Set the node as visited
            G.visited[temp] = 1;
 
            // Iterate from the minimum
            // value to maximum value in
            // the current component
            for (int j = G.minimum_node[temp];
                 j <= G.maximum_node[temp]; j++) {
 
                // If the nodes are in
                // different components
                if (G.getsuperparent(j)
                    != G.getsuperparent(i)) {
 
                    // Unite them
                    G.unite(i, j);
 
                    // Increment the answer
                    answer++;
                }
            }
        }
    }
 
    // Return the answer
    return answer;
}
 
// Driver Code
int32_t main()
{
    int N = 7, M = 3;
 
    G.init(N);
 
    // Insert edges
    G.unite(1, 5);
    G.unite(2, 4);
    G.unite(3, 4);
 
    cout << minimumEdgesToBeAdded(N);
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
 
static final int MOD = 1000000007;
 
// Disjoint Set Union
static class dsu
{
    public dsu(){}
 
    // Stores the parent
    // of each node
    int[] parent;
 
    // Storing maximum value
    // in each component
    int[] maximum_node;
 
    // Stores the minimum value
    // in each component
    int[] minimum_node;
 
    // Stores the visited nodes
    int[] visited;
 
    // Function to initialize the
    // values in vectors
    void init(int n)
    {
         
        // Initialize the size of
        // vectors as n
        parent = new int[n];
        maximum_node = new int[n];
        minimum_node = new int[n];
        visited = new int[n];
 
        for(int i = 0; i < n; i++)
        {
             
            // Initially every component
            // has only one node
            parent[i] = i;
            maximum_node[i] = i;
            minimum_node[i] = i;
 
            // Mark unvisited
            visited[i] = 0;
        }
    }
 
    // Function to get identifier node
    // (superparent) for each component
    int getsuperparent(int x)
    {
 
        // If parent of a node is that
        // node itself then the node is
        // superparent of that component
        if(x == parent[x])
            return x;
        else
        {
            parent[x] = getsuperparent(parent[x]);
            return parent[x];
        }
    }
 
    // Function to perform union of two
    // different components
    void unite(int x, int y)
    {
        int superparent_x = getsuperparent(x);
        int superparent_y = getsuperparent(y);
 
        // Set superparent of y as the
        // parent of superparent of x
        parent[superparent_x] = superparent_y;
 
        // Update the maximum node
        // in the component containing y
        maximum_node[superparent_y] = Math.max(
        maximum_node[superparent_y],
        maximum_node[superparent_x]);
 
        // Update the minimum node
        // in the component containing y
        minimum_node[superparent_y] = Math.min(
        minimum_node[superparent_y],
        minimum_node[superparent_x]);
    }
};
 
static dsu G = new dsu();
 
// Function to find the minimum number
// of edges to be added to the Graph
static int minimumEdgesToBeAdded(int n)
{
     
    // Stores the answer
    int answer = 0;
 
    // Iterate over all nodes
    for(int i = 0; i < n; i++)
    {
         
        // Get the superparent of
        // the current node
        int temp = G.getsuperparent(i);
 
        // If the node is not visited
        if (G.visited[temp] == 0)
        {
             
            // Set the node as visited
            G.visited[temp] = 1;
 
            // Iterate from the minimum
            // value to maximum value in
            // the current component
            for(int j = G.minimum_node[temp];
                   j <= G.maximum_node[temp]; j++)
            {
                 
                // If the nodes are in
                // different components
                if (G.getsuperparent(j) !=
                    G.getsuperparent(i))
                {
                     
                    // Unite them
                    G.unite(i, j);
 
                    // Increment the answer
                    answer++;
                }
            }
        }
    }
     
    // Return the answer
    return answer;
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 7;
 
    G.init(N);
 
    // Insert edges
    G.unite(1, 5);
    G.unite(2, 4);
    G.unite(3, 4);
 
    System.out.print(minimumEdgesToBeAdded(N));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program to implement
# the above approach
MOD = 1000000007
 
# Disjoint Set Union
class dsu:
 
    # Function to initialize the
    # values in vectors
    def __init__(self, n: int) -> None:
         
        # Stores the parent
        # of each node
        self.parent = [i for i in range(n)]
         
        # Storing maximum value
        # in each component
        self.maximum_node = [i for i in range(n)]
         
        # Stores the minimum value
        # in each component
        self.minimum_node = [i for i in range(n)]
         
        # Stores the visited nodes
        self.visited = [0] * n
 
    # Function to get identifier node
    # (superparent) for each component
    def getsuperparent(self, x: int) -> int:
         
        # If parent of a node is that
        # node itself then the node is
        # superparent of that component
        if x == self.parent[x]:
            return x
        else:
            self.parent[x] = self.getsuperparent(
                self.parent[x])
            return self.parent[x]
 
    # Function to perform union of two
    # different components
    def unite(self, x: int, y: int) -> None:
 
        superparent_x = self.getsuperparent(x)
        superparent_y = self.getsuperparent(y)
 
        # Set superparent of y as the
        # parent of superparent of x
        self.parent[superparent_x] = superparent_y
 
        # Update the maximum node
        # in the component containing y
        self.maximum_node[superparent_y] = max(
            self.maximum_node[superparent_y],
            self.maximum_node[superparent_x])
 
        # Update the minimum node
        # in the component containing y
        self.minimum_node[superparent_y] = min(
            self.minimum_node[superparent_y],
            self.minimum_node[superparent_x])
 
# Function to find the minimum number
# of edges to be added to the Graph
def minimumEdgesToBeAdded(n: int) -> int:
 
    global G
 
    # Stores the answer
    answer = 0
 
    # Iterate over all nodes
    for i in range(n):
 
        # Get the superparent of
        # the current node
        temp = G.getsuperparent(i)
 
        # If the node is not visited
        if (not G.visited[temp]):
 
            # Set the node as visited
            G.visited[temp] = 1
 
            # Iterate from the minimum
            # value to maximum value in
            # the current component
            for j in range(G.minimum_node[temp],
                           G.maximum_node[temp] + 1):
                                
                # If the nodes are in
                # different components
                if (G.getsuperparent(j) !=
                    G.getsuperparent(i)):
 
                    # Unite them
                    G.unite(i, j)
 
                    # Increment the answer
                    answer += 1
 
    # Return the answer
    return answer
 
# Driver Code
if __name__ == "__main__":
 
    N = 7
    M = 3
 
    G = dsu(N)
 
    # Insert edges
    G.unite(1, 5)
    G.unite(2, 4)
    G.unite(3, 4)
     
    print(minimumEdgesToBeAdded(N))
 
# This code is contributed by sanjeev2552


C#
// C# program to implement
// the above approach
using System;
 
class GFG{
 
//static readonly int MOD = 1000000007;
 
// Disjoint Set Union
class dsu
{
    public dsu(){}
 
    // Stores the parent
    // of each node
    public int[] parent;
 
    // Storing maximum value
    // in each component
    public int[] maximum_node;
 
    // Stores the minimum value
    // in each component
    public int[] minimum_node;
 
    // Stores the visited nodes
    public int[] visited;
 
    // Function to initialize the
    // values in vectors
    public void init(int n)
    {
         
        // Initialize the size of
        // vectors as n
        parent = new int[n];
        maximum_node = new int[n];
        minimum_node = new int[n];
        visited = new int[n];
 
        for(int i = 0; i < n; i++)
        {
             
            // Initially every component
            // has only one node
            parent[i] = i;
            maximum_node[i] = i;
            minimum_node[i] = i;
 
            // Mark unvisited
            visited[i] = 0;
        }
    }
 
    // Function to get identifier node
    // (superparent) for each component
    public int getsuperparent(int x)
    {
 
        // If parent of a node is that
        // node itself then the node is
        // superparent of that component
        if(x == parent[x])
            return x;
        else
        {
            parent[x] = getsuperparent(parent[x]);
            return parent[x];
        }
    }
 
    // Function to perform union of two
    // different components
    public void unite(int x, int y)
    {
        int superparent_x = getsuperparent(x);
        int superparent_y = getsuperparent(y);
 
        // Set superparent of y as the
        // parent of superparent of x
        parent[superparent_x] = superparent_y;
 
        // Update the maximum node
        // in the component containing y
        maximum_node[superparent_y] = Math.Max(
        maximum_node[superparent_y],
        maximum_node[superparent_x]);
 
        // Update the minimum node
        // in the component containing y
        minimum_node[superparent_y] = Math.Min(
        minimum_node[superparent_y],
        minimum_node[superparent_x]);
    }
};
 
static dsu G = new dsu();
 
// Function to find the minimum number
// of edges to be added to the Graph
static int minimumEdgesToBeAdded(int n)
{
     
    // Stores the answer
    int answer = 0;
 
    // Iterate over all nodes
    for(int i = 0; i < n; i++)
    {
         
        // Get the superparent of
        // the current node
        int temp = G.getsuperparent(i);
 
        // If the node is not visited
        if (G.visited[temp] == 0)
        {
             
            // Set the node as visited
            G.visited[temp] = 1;
 
            // Iterate from the minimum
            // value to maximum value in
            // the current component
            for(int j = G.minimum_node[temp];
                   j <= G.maximum_node[temp]; j++)
            {
                 
                // If the nodes are in
                // different components
                if (G.getsuperparent(j) !=
                    G.getsuperparent(i))
                {
                     
                    // Unite them
                    G.unite(i, j);
 
                    // Increment the answer
                    answer++;
                }
            }
        }
    }
     
    // Return the answer
    return answer;
}
 
// Driver Code
public static void Main(String[] args)
{
    int N = 7;
 
    G.init(N);
 
    // Insert edges
    G.unite(1, 5);
    G.unite(2, 4);
    G.unite(3, 4);
 
    Console.Write(minimumEdgesToBeAdded(N));
}
}
 
// This code is contributed by Rajput-Ji


Javascript


输出:
1

时间复杂度: O(N),其中 N 是图中的节点数。
辅助空间: O(N)

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