题目描述
给定从 0 到 n-1 标号的 n 个结点,和一个无向边列表(每条边以结点对来表示),请编写一个函数用来判断这些边是否能够形成一个合法有效的树结构。
示例 1:
输入: n = 5, 边列表 edges = [[0,1], [0,2], [0,3], [1,4]]
输出: true示例 2:
输入: n = 5, 边列表 edges = [[0,1], [1,2], [2,3], [1,3], [1,4]]
输出: false注意:你可以假定边列表 edges 中不会出现重复的边。由于所有的边是无向边,边 [0,1] 和边 [1,0] 是相同的,因此不会同时出现在边列表 edges 中。
算法分析
判断一个图是否为树结构就是判断这个图是否有环,如果无环且连同分量为1,则是树结构
代码
class Solution {
public:
vector<int> parents;
vector<int> ranks;
void initUnion(int n) {
parents.resize(n);
ranks.resize(n, 1);
for(int i = 0; i < n; ++i) {
parents[i] = i;
}
}
int find(int x) {
return x == parents[x] ? x:parents[x]=find(parents[x]);
}
bool merge(int i, int j) {
int iroot = find(i);
int jroot = find(j);
if(iroot == jroot) {
return false;
}
if(ranks[iroot] <= ranks[jroot]) {
parents[iroot] = jroot;
} else {
parents[jroot] = iroot;
}
if(ranks[iroot] == ranks[jroot] && iroot != jroot) {
ranks[jroot]++;
}
return true;
}
bool validTree(int n, vector<vector<int>>& edges) {
if(edges.size() != n - 1) {
return false;
}
initUnion(n);
for(auto &edge: edges) {
if(!merge(edge[0], edge[1])) {
return false;
}
}
return true;
}
};