684. 冗余连接

题目描述

树可以看成是一个连通且无环的无向图。
给定往一棵 n 个节点 (节点值 1~n) 的树中添加一条边后的图。添加的边的两个顶点包含在 1 到 n 中间,且这条附加的边不属于树中已存在的边。图的信息记录于长度为 n 的二维数组 edges ,edges[i] = [ai, bi] 表示图中在 ai 和 bi 之间存在一条边。
请找出一条可以删去的边,删除后可使得剩余部分是一个有着 n 个节点的树。如果有多个答案,则返回数组 edges 中最后出现的边。

  • 示例

    输入: edges = [[1,2], [1,3], [2,3]]
    输出: [2,3]

解决方案

并查集
遍历每一条边,如果未加入某条边时,两边的顶点已在同一连通分量中,那么此边即为冗余连接,加上之后会形成环。

class UnionFind {
private:
    int count;
    vector<int> parent;
public:
    UnionFind(int n) : parent(n) {
        int start=1;
        count=n-start;
        for (int i=start;i<n;i++) {
            parent[i]=i;
        }
    }

    /* 查找根节点 */
    int findRoot(int x) {
        if (x!=parent[x]) {
            parent[x]=findRoot(parent[x]);
        }

        return parent[x];
    }

    /* 合并操作 */
    void unionRoot(int x, int y) {
        int root_x=findRoot(x);
        int root_y=findRoot(y);
        if (root_x != root_y) {
            parent[root_x]=root_y;
            count--;
        }
    }

    /* 判断x,y是否属于同一连通分量 */
    bool isConnect(int x, int y) {
        return findRoot(x)==findRoot(y);
    }

    /* 返回连通分量个数 */
    int getCount() {
        return count;
    }
};

class Solution {
public:
    vector<int> findRedundantConnection(vector<vector<int>>& edges) {
        int n=edges.size();
        UnionFind unionFind(n+1);

        for (auto &edge:edges) {
            int p=edge[0];
            int q=edge[1];
            if (unionFind.findRoot(p)!=unionFind.findRoot(q)) {
                unionFind.unionRoot(p,q);
            } else {
                return edge;
            }
        }

        return vector<int>{};
    }
};
原文地址:https://www.cnblogs.com/hunter-w/p/15044972.html