给定一个大小为N的数组 A[] ,对于[0, N)范围内的每个索引 i ,值A[i]表示节点 i的连通分量的大小。任务是找到可能图的边,否则打印-1。
Note: There may be more than 1 possible answers for each array. Print any one of them.
例子:
Input: N = 5, A[] = {2, 1, 1, 2, 1}
Output: {{0, 3}}
Explanation: The size of Connected Components of nodes (0, 3) is 2, every other node is singular.
Input: N = 4, A[] = {2, 2, 2, 2}
Output: {{0, 1}, {2, 3}}
Explanation: Other possible variations are – {{0, 2}, {1, 3}}, {{0, 3}, {1, 2}}
Input: N=2, A[] = {1, 1}
Output: Graph is already connected.
Explanation: Since, each connected component size is 1, no edge is needed to connect any pair of nodes.
方法:这个想法是观察所有相同的组件大小可以使用等于数组值大小的总节点相互连接。因此,将具有相同索引值的所有节点存储到映射中。节点的值可以用映射结构 map
- 将布尔变量flag初始化为false以检查所有值是否为1。如果是,则无需形成任何边。
- 初始化向量mp[]的映射以存储特定连通分量大小的索引。
- 使用变量i在范围[0, N) 上迭代并执行以下任务:
- 将值i推入地图中 A[i]处的向量中。
- 如果A[i]不等于1,则将 flag 的值设置为true 。
- 如果flag为false,则返回。
- 使用变量x遍历地图并执行以下任务:
- 如果x.second.size()不能被x.first整除,则打印-1并返回0 。
- 初始化一对 int边 []的向量以存储边。
- 使用变量x遍历地图并执行以下任务:
- 将向量nodes[]初始化为当前位置的向量。
- 在while循环中迭代直到nodes[]的大小大于0并执行以下任务:
- 将变量cnt初始化为0。
- 初始化向量component_nodes[]。
- 在 while 循环中迭代直到cnt不等于x.first并执行以下任务:
- 将向量 nodes[] 中的 lat 值推入向量component_nodes[]并从 nodes[]弹出该值并将 cnt的值增加1。
- 使用变量i迭代范围[1, component_nodes.size())并执行以下任务:
- 将{component_nodes[i], component_nodes[i-1]} 对推入向量edge[] 中。
- 执行完上述步骤后,打印向量edges[]作为答案。
下面是上述方法的实现:
C++
// C++ Program for the above approach
#include
using namespace std;
// Function to construct the graph for
// the given array
int constructConnectedComponent(int A[], int N)
{
// Variable to check if all the values
// are 1, then no need to form any edge
bool flag = false;
// Iterate through the array and store
// the indices in a
// map of same size connected component
map > mp;
for (int i = 0; i < N; i++) {
mp[A[i]].push_back(i);
if (A[i] != 1)
flag = true;
}
if (!flag) {
cout << "Graph already connected.\n";
return 0;
}
// Check if the total size of vector is a
// multiple of size
for (auto x : mp) {
if ((x.second).size() % x.first != 0) {
cout << -1;
return 0;
}
}
// Make a vector to store the edges
vector > edges;
// Start constructing edges with each multiple
// from the corresponding vector
for (auto x : mp) {
vector nodes = x.second;
while (!nodes.empty()) {
int cnt = 0;
vector component_nodes;
while (cnt != x.first) {
component_nodes.push_back(nodes.back());
nodes.pop_back();
cnt++;
}
// Make edges between selected node
for (int i = 1; i < component_nodes.size();
i++) {
edges.push_back(
make_pair(component_nodes[i],
component_nodes[i - 1]));
}
}
}
// Print the edges of the graph
cout << "[";
for (int i = 0; i < edges.size(); i++) {
cout << "{" << edges[i].first << ", "
<< edges[i].second << "}";
if (i != edges.size() - 1) {
cout << ", ";
}
}
cout << "]";
return 0;
}
// Driver Code
int main()
{
int N = 5;
int A[] = { 2, 1, 1, 2, 1 };
constructConnectedComponent(A, N);
return 0;
}
[{0, 3}]
时间复杂度: O(N*log(N))
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。