鉴于由N一图中的节点编号为0到N – 1和对{A,B}的形式m条边中,任务是找到边缘的最小数量的要被添加到所述图形,使得如果存在一个从任何节点a到节点b 的路径,那么也应该有从节点a到节点[ a + 1, a + 2, a + 3, …, b – 1] 的路径。
例子:
Input: N = 7, M = 3, Edges[][] = {{1, 5}, {2, 4}, {3, 4}}
Output: 1
Explanation:
There is a path from 1 to 5. So there should be paths from 1 to 2, 3 and 4 as well.
Adding an edge {1, 2} will be sufficient to reach the other two nodes of the graph.
Input: N = 8, M = 3 Edges[][] = {{1, 2}, {2, 3}, {3, 4}}
Output: 0
方法:
这个想法是使用不相交集或联合查找。不相交集中的每个组件都应该有连续的节点。这可以通过维护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 现场工作专业课程和学生竞争性编程现场课程。