LeetCode 261. Graph Valid Tree


Given  n  nodes labeled from  0  to  n - 1  and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.
For example:
Given  n = 5  and  edges = [[0, 1], [0, 2], [0, 3], [1, 4]] , return  true .
Given  n = 5  and  edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]] , return  false .
Hint:
Given  n = 5  and  edges = [[0, 1], [1, 2], [3, 4]] , what should your return? Is this case a valid tree? Show More Hint 
Note: you can assume that no duplicate edges will appear in  edges . Since all edges are undirected,  [0, 1]  is the same as  [1, 0]  and thus will not appear together in  edges .
Method 1: Union-Find Algorithm
#include 
#include 
using namespace std;
// this is actually to use union-find.
bool find(vector& id, int p, int q) {
  return id[p] == id[q];
}

int root(vector& id, int p) {
  while(p != id[p]) {
    p = id[p];
  }
  return p;
}

void unite(vector& id, int p, int q) {
  int root_p = root(id, p);
  int root_q = root(id, q);
  id[root_p] = root_q;
}

bool isValidTree(int n, vector< vector >& edges) {
  if(n < 0 || (n - 1) != edges.size()) return false;
  vector id(n);
  for(int i = 0; i < n; ++i) {
    id[i] = i;
  }
  for(int i = 0; i < edges.size(); ++i) {
    if(find(id, edges[i][0], edges[i][1])) {
      return false;
    } else {
      unite(id, edges[i][0], edges[i][1]);
    }
  }
  return true;
}

int main(void) {
  vector< vector > edges{{0, 1}, {0, 2}, {0, 3}, {1, 4}};
  vector< vector > edges_1{{0, 1}, {1, 2}, {2, 3}, {1, 3}, {1, 4}};
  cout << isValidTree(5, edges) << endl;
  cout << isValidTree(5, edges_1) << endl;
}

If could't think up Union-Find method, it is also Ok to to use DFS to detect cycle. If cycle found, that is not a valid graph tree.
Step:
 1: first build up hashmap hashmap[first].push_back(second), hashmap[second].push_back(first)
 2: Make all the node unvisited.
 3: Loop all the node, if found an unvisited node, using dfs to detect cycle. Note: here we need to pass the parent node in to dfs function
    bool dfs(nodesMap, currNode, parentNode, visited) {
         visited[curreNode] = true;
        for(v : edges) {
             if(unvisited) {if(dfs(nodesMap, v, currentNode, visited)) return true;}
             else if( *v != parentNode) return ture//cycle detected
        }
      return false//there is no cycle.
    }
   if(dfs) return false//cycle in the undirected graph, that is not a valid tree.
Beside checking whether there is a cycle, we also need to check whether the given nodes forms a forest.