题目描述
树可以看成是一个连通且无环的无向图。
给定往一棵 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>{};
}
};