Leetcode 684 冗余连接 (并差集)

题目描述:

  在本问题中, 树指的是一个连通且无环的无向图。输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, ..., N) 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。答案边 [u, v] 应满足相同的格式 u < v。

题解:

  由于题目限制了图在不加上多余边的情况下是一个连通且无环的无向图。那么依次添加题目给出边,利用并查集判断将要添加的边的两个顶点是否已经联通,如果已经联通那么这条边就是多余的了。

(一开始想着用拓扑排序判断环啥的,有点麻烦了。还有就是要抓住一个特性,添加边出现环的时候,这条边就是多余的边

AC代码:

class Solution {
public:
    // 一般来说找到一定的规律就好了
    int Find(int x)
    {
        int root = x;
        while(pre[root] != root) root = pre[root];

        // 路径压缩
        while(pre[x] != x)
        {
            int tmp = pre[x];
            pre[x] = root;
            x = tmp;
        } 

        return root;
    }
    int Merge(int x,int y)
    {
        int xx = Find(x);
        int yy = Find(y);
        if(xx == yy) return 1;
        if(xx != yy) pre[xx] = yy;
        return 0;
    }
    vector<int> findRedundantConnection(vector<vector<int>>& edges) {
        int Len = edges.size();
        for(int i=0;i<Len;i++) pre[i] = i;
        vector<int> ans;
        for(auto & edge:edges)
        {
            int flag = Merge(edge[0],edge[1]);
            if(flag == 1)
            {
                ans.push_back(edge[0]);
                ans.push_back(edge[1]);
                break;
            }
        }
        return ans;
    }
private:
    int pre[1100];
};
原文地址:https://www.cnblogs.com/z1141000271/p/12653640.html