📌  相关文章
📜  根据每个节点的组件大小构造一个图

📅  最后修改于: 2021-10-26 06:41:02             🧑  作者: Mango

给定一个大小为N的数组 A[] ,对于[0, N)范围内的每个索引 i ,值A[i]表示节点 i的连通分量的大小。任务是找到可能图的边,否则打印-1。

例子:

方法:这个想法是观察所有相同的组件大小可以使用等于数组值大小的总节点相互连接。因此,将具有相同索引值的所有节点存储到映射中。节点的值可以用映射结构 map> 存储。检查每个连通分量的大小,对应的总节点数是大小的倍数。如果对于任何连接的组件,上述条件失败,则将没有有效的图形。立即返回-1。否则对于所有多个存储顶点并将它们相邻连接。将所有边存储在一个数组中并输出结果。请按照以下步骤解决问题:

  • 将布尔变量flag初始化为false以检查所有值是否为1。如果是,则无需形成任何边。
  • 初始化向量mp[]的映射以存储特定连通分量大小的索引。
  • 使用变量i在范围[0, N) 上迭代并执行以下任务:
    • 将值i推入地图中 A[i]处的向量中。
    • 如果A[i]不等于1,则将 flag 的值设置为true
  • 如果flagfalse,则返回。
  • 使用变量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 现场工作专业课程学生竞争性编程现场课程。