查找不断开图的边删除
给定从0到N-1编号的N个顶点和E条边,形成一个无向图。应按给定顺序添加所有边。任务是找到不断开图形的边删除。如果有多个可能的边返回序列中稍后出现的边。
例子:
Input: N = 3, E = 3, edges= {{0, 1}, {1, 2}, {0, 2}}
Output: 0 2
Explanation: Removing any one of the edges keep the graph connected.
But (0, 2) comes later in the sequence.
Input: N = 5, E = 7, edges = {{0, 1}, {1, 2}, {2, 3}, {4, 3}, {0, 4}, {4, 1}, {3, 0}}
Output:
0 4
4 1
3 0
Explanation: After removing the edges (0, 4), (4, 1), (3, 0) the graph will still be connected. Hence, these three edges are extra edges.
方法:这个问题可以用不相交集的概念来解决 基于以下思想的数据结构:
Keep connecting the edges to each other if they are previously not been connected, if they are already connected then the current edge for sure be an extra edge.
使用不相交集来查找节点以前是否连接过。如果它们已连接,则连接边缘并合并这两组。
请按照以下步骤解决问题:
- 创建一个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)