684. 冗余连接

在本问题中, 树指的是一个连通且无环的无向图。
输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, ..., N) 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。

结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。

返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。答案边 [u, v] 应满足相同的格式 u < v。

解决方案

并查集:
并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题。一些常见的用途有求连通子图、求最小生成树的 Kruskal 算法和求最近公共祖先(Least Common Ancestors, LCA)等。
开始时,每个元素各自属于一个集合,之后根据条件,将属于同一个组的集合进行合并。

并查集的基本操作有三个:

makeSet(s):建立一个新的并查集,其中包含 s 个单元素集合。
unionSet(x, y):把元素 x 和元素 y 所在的集合合并,要求 x 和 y 所在的集合不相交,如果相交则不合并。
find(x):找到元素 x 所在的集合的代表,该操作也可以用于判断两个元素是否位于同一个集合,只要将它们各自的代表比较一下就可以了。
对于本题而言,可以将具有相同根节点的集合合并为同一个集合。对于一棵树而言,每条边都会把一个新的节点加入到集合中。如果一条边的两个节点已经在同一个节点中,则该边是冗余边。
具体实现如下:

class Solution {
public:
    int find(int x, vector& parent)
    {
        while(x != parent[x])
        {
            x = parent[x];
        }
        return x;
    }
    bool union_node(int x, int y, vector& parent)
    {
        int px = find(x, parent);
        int py = find(y, parent);
        if(px != py)
        {
            parent[py] = px;
            return true; 
        }
        return false;
    }
    vector findRedundantConnection(vector>& edges) {
        int n = edges.size();
        vector parent(n + 1);
        for(int i=1;i<=n;i++)
        {
            parent[i] = i;
        }
        for(int i=0;i res;
        return res;
    }
};

你可能感兴趣的:(684. 冗余连接)