📜  查找不断开图的边删除

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

查找不断开图的边删除

给定从0N-1编号的N个顶点和E条边,形成一个无向图。应按给定顺序添加所有边。任务是找到不断开图形的边删除。如果有多个可能的边返回序列中稍后出现的边。

例子:

方法:这个问题可以用不相交集的概念来解决 基于以下思想的数据结构:

使用不相交集来查找节点以前是否连接过。如果它们已连接,则连接边缘并合并这两组。

请按照以下步骤解决问题:

  • 创建一个parent[]数组来存储每个节点的父节点。
  • 创建一组对(比如ans 来存储答案。
  • 通过给定的边运行一个循环。
    • 检查当前边的顶点是否已经连接。
    • 如果它们已连接,则将此边缘存储到ans中。
    • 否则,连接这两个顶点并将这两个不相交的集合合并(即,使它们的父节点相同)。
  • 返回并打印ans

下面是上述方法的实现:

C++
// C++ code to implement the above approach
  
#include 
using namespace std;
  
// The required Comparator Function.
int find(int x, vector& parent)
{
    if (x == parent[x]) {
        return x;
    }
    return parent[x]
           = find(parent[x], parent);
}
  
// Function to find extra edges
set > extraEdges(int n, int e,
                                vector >& edges)
{
    set > ans;
    vector parent(n);
    for (int i = 0; i < n; i++) {
        parent[i] = i;
    }
  
    // Loop through the edges
    for (auto x : edges) {
        int vParent = find(x[0], parent);
        int uParent = find(x[1], parent);
        if (vParent == uParent) {
            pair p;
            if (x[0] < x[1]) {
                p = { x[0], x[1] };
            }
            else {
                p = { x[1], x[0] };
            }
            ans.insert(p);
        }
        else {
            parent[vParent] = uParent;
        }
    }
  
    // Return the edges
    return ans;
}
  
// Driver code
int main()
{
    int N = 3, E = 3;
    vector > edges
        = { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 2 } };
    set > ans = extraEdges(N,
                                          E, edges);
    for (auto& edge : ans) {
        cout << edge.first << " " << edge.second << "\n";
    }
    return 0;
}


输出
0 2

时间复杂度: O(E * log(N))
辅助空间: O(N)