题目解析
题目来源
class Solution {
public:
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
}
};
题目解析
并查集
因为它是一个双向图,所以我们可以将联通的所有节点加到一个集合中,然后看它们的父节点是否相同
class Solution {
class UnionFind{
std::vector<int> parent; // parent[i] = k : i的父亲是k
std::vector<int> size; // size[i] = k : 如果i是代表节点,size[i]才有意义( i所在的集合大小是多少),否则无意义
std::vector<int> help;
int cnt;
int findRoot(int i){
int hi = 0;
while (i != parent[i]){
help[hi++] = parent[i];
i = parent[i];
}
for (hi--; hi >= 0; --hi) {
parent[help[hi]] = i;
}
return i;
}
public:
explicit UnionFind(int n){
cnt = n;
parent.resize(n);
size.resize(n);
help.resize(n);
for (int i = 0; i < n; ++i) {
parent[i] = i;
size[i] = 1;
}
}
void merge(int i, int j){
int f1 = findRoot(i);
int f2 = findRoot(j);
if(f1 != f2){
if(size[f1] >= size[f2]){
parent[f2] = f1;
size[f1] = size[f1] + size[f2];
}else{
parent[f1] = f2;
size[f2] = size[f2] + size[f1];
}
--cnt;
}
}
int counts() const{
return cnt;
}
bool isConnected(int p, int q){
return findRoot(p) == findRoot(q);
}
};
public:
bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
UnionFind unionFind(n);
for (auto & edge : edges) {
unionFind.merge(edge[0], edge[1]);
}
return unionFind.isConnected(source, destination);
}
};