图是否是树

来源:互联网 发布:国产电视机 知乎 编辑:程序博客网 时间:2024/05/17 07:18

题目描述

给出 n 个节点,标号分别从 0 到 n - 1 并且给出一个 无向 边的列表 (给出每条边的两个顶点),
写一个函数去判断这张`无向`图是否是一棵树

注意事项

你可以假设我们不会给出重复的边在边的列表当中. 无向边 [0, 1] 和 [1, 0] 是同一条边,
因此他们不会同时出现在我们给你的边的列表当中。

样例
给出n = 5 并且 edges = [[0, 1], [0, 2], [0, 3], [1, 4]], 返回 true.

给出n = 5 并且 edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], 返回 false.


解法一

首先建立邻接矩阵neighbor

然后用一个vector保存每个节点访问状态

紧接着遍历图,看是否存在环。存在环则不是树。

最后看visited是不是每个节点都遍历了(判断是否存在孤立节点)。

如果存在节点没有访问过,说明图没有全部连通,则该图不是树。

class Solution {public:    /**     * @param n an integer     * @param edges a list of undirected edges     * @return true if it's a valid tree, or false     */    bool validTree(int n, vector<vector<int>>& edges) {        // Write your code here        vector<vector<int>> ne(n);        vector<bool> j(n,0);        for(int i=0; i<edges.size(); i++){            ne[edges[i][0]].push_back(edges[i][1]);            ne[edges[i][1]].push_back(edges[i][0]);        }        if(hascycle(ne,j,-1,0))            return false;        for(int i=0; i<n; i++)            if(!j[i])                return false;        return true;    }    bool hascycle(vector<vector<int>>&n, vector<bool>& j,int par, int kid){        if(j[kid])            return true;        j[kid]=true;        for(int i=0; i<n[kid].size();i++)            if(par!=n[kid][i] && hascycle(n,j,kid,n[kid][i]))                return true;        return false;    }};

解法二

想象一开始这个图只有顶点,没有边,我们来一条一条的添加边。

刚开始有多少个节点就有多少集合,集合里面的任意两点有且只有一条路径可达。然后每遇到一条边,就判断这边的两个端点是否在同一个集合里?

  • 在的话,表示有环:因为两个点在一个集合里就表示这两个点已经有一条路径了,现在再加一条路径,必然构成环。

  • 不在的话,表示不构成环,我们应该合并这两个集合:因为加上这条边,两个集合就被连起来了,合并成了一个集合

class Solution {public:    /**     * @param n an integer     * @param edges a list of undirected edges     * @return true if it's a valid tree, or false     */    bool validTree(int n, vector<vector<int>>& edges) {        // Write your code here        if(edges.size() != n-1)            return false;        vector<int> root(n);        for (int i=0; i<n; i++)            root[i] = i;        for (int i=0; i<edges.size(); i++) {            int root1 = findRoot(root, edges[i][0]);            int root2 = findRoot(root, edges[i][1]);            if (root1 == root2)                return false;            root[root2] = root1;        }        return true;    }    int findRoot(vector<int>& root, int n) {        while (n != root[n])            n = root[n];        return n;    }};
原创粉丝点击