LeetCode 261. Graph Valid Tree Detect Cycle In Directed/Undirected Graph

DFS

https://www.geeksforgeeks.org/check-given-graph-tree/

Graph Tree is a determination whether there are two conditions: 1) communicates FIG. 2) without ring

This question is undirected graph, there is determined dfs ring can do, much easier than having to FIG.

FIG determining whether a cycloalkyl dfs: Detect the In Cycle Directed / undirected Graph

FIG determines whether communication is very easy, after a Node dfs, is not only to look over all nodes to visit.

We can also use knowledge of graph theory, for the Tree, | E | = | V | -1

The time complexity of O (V + E)

class Solution {
public:
    vector<list<int>> adj;
    
    bool validTree(int n, vector<vector<int>>& edges) {
        adj.resize(n,list<int>());
        for (auto edge:edges){
            int u=edge[0], v=edge[1];
            adj[u].push_back(v);
            adj[v].push_back(u);
        }
        vector<bool> visited(n,false);
        if (dfs(0,visited,-1)) return false;
        for (bool x:visited){
            if (x==false) return false;
        }
        return true;
    }
    
    bool dfs(int i, vector<bool> &visited, int parent){ // return if has cycle
        visited[i] = true;
        for (auto x:adj[i]){
            if (visited[x] && x!=parent) return true;
            if (!visited[x]){
                if (dfs(x,visited,i))
                    return true;
            }
        }
        return false;
    }
};

 

Union Find 

https://www.geeksforgeeks.org/union-find-algorithm-set-2-union-by-rank/

With uniond find to do it is possible, and more intuitive. Since node 0 ~ n-1, it can be done by a parent array.

Then do with the array size is relatively simple to determine how the union, with the parent [root] = - size can.

Time complexity is more complex, if there is no path compression, union and find all need logV, so the overall complexity is ElogV.

After adding path compression, union and find are amortized O (1).

class Solution {
public:
    vector<int> parent;
    
    bool validTree(int n, vector<vector<int>>& edges) {
        if (edges.size()!=n-1) return false;
        
        parent.resize(n,-1);
        for (auto edge:edges){
            int u=edge[0], v=edge[1];
            int root1=Find(u), root2=Find(v);
            if (root1==root2) return false;
            
            // whoever's size is bigger becomes parent of other
            // notice parent[root] is negative, if parent[root] is smaller, then its size is larger
            if (root1>root2){
                parent[root2] += parent[root1];
                parent[root1] = root2;
            }else{
                parent[root1] += parent[root2];
                parent[root2] = root1;
            }
        }
        return true;
    }
    
    int Find(int x){
        if (parent[x]<0) return x;
        return parent[x]=Find(parent[x]);
    }
};

Guess you like

Origin www.cnblogs.com/hankunyan/p/10965551.html