178题 Graph Valid Tree

该博客探讨了一个算法问题,即如何检查给定的无向边是否组成一棵有效的树。解决方案中,首先检查节点数量和边的数量是否满足树的特性,然后使用图的数据结构和广度优先搜索(BFS)遍历所有节点来验证是否存在环路。若所有节点都被访问且没有环,则判断为有效树。

Graph Valid Tree

Description
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.

public class Solution {
    /**
     * @param n: An integer
     * @param edges: a list of undirected edges
     * @return: true if it's a valid tree, or false
     */
    public boolean validTree(int n, int[][] edges) {
        // write your code here
        if(n == 0){
            return false ;
        }
        if(edges.length != n-1){
            return false ;
        }
        Map<Integer, Set<Integer>> graph = getGraph(n , edges);
        Queue<Integer> queue = new LinkedList<Integer>();
        HashSet<Integer> set = new HashSet<Integer>();
        queue.offer(0) ;
        set.add(0);
        while(! queue.isEmpty()){
            int node = queue.poll() ;
            for(Integer neighbor : graph.get(node)){
                if(set.contains(neighbor)){
                    continue ;
                }
                queue.offer(neighbor);
                set.add(neighbor);
            }
        }
        return (set.size() == n) ;

    }
    public Map<Integer, Set<Integer>> getGraph(int n, int[][] edges){
         Map<Integer, Set<Integer>> graph = new HashMap<Integer, Set<Integer>>();
         for(int i= 0 ; i < n ; i++){
             graph.put(i , new HashSet<Integer>());
         }
         for(int i=0 ; i < edges.length ; i++){
             int u = edges[i][0];
             int v = edges[i][1];
             graph.get(u).add(v);
             graph.get(v).add(u);
         }
         return graph ;
    }
}
将图转换为树是图论中一个重要的问,以下介绍几种常见的方法和算法: ### 最小生成树算法 最小生成树(MST)算法适用于加权连通图,其目标是找到一个包含图中所有顶点的树,且树中所有边的权值之和最小。常见的最小生成树算法有Prim算法和Kruskal算法: - **Prim算法**:从图中任意一个顶点开始,逐步扩展树,每次选择连接树和图中其他顶点的边中权值最小的边,直到所有顶点都被包含在树中。以下是Prim算法的Python示例代码: ```python import heapq def prim(graph): num_vertices = len(graph) mst = [] visited = [False] * num_vertices start_vertex = 0 pq = [(0, start_vertex, None)] while pq: weight, current_vertex, parent_vertex = heapq.heappop(pq) if visited[current_vertex]: continue visited[current_vertex] = True if parent_vertex is not None: mst.append((parent_vertex, current_vertex, weight)) for neighbor, edge_weight in graph[current_vertex]: if not visited[neighbor]: heapq.heappush(pq, (edge_weight, neighbor, current_vertex)) return mst ``` - **Kruskal算法**:将图中所有边按照权值从小到大排序,然后依次选择边加入树中,但要保证加入的边不会形成环,直到树中包含所有顶点。以下是Kruskal算法的Python示例代码: ```python class UnionFind: def __init__(self, n): self.parent = list(range(n)) def find(self, x): if self.parent[x] != x: self.parent[x] = self.find(self.parent[x]) return self.parent[x] def union(self, x, y): root_x = self.find(x) root_y = self.find(y) if root_x != root_y: self.parent[root_x] = root_y def kruskal(graph): num_vertices = len(graph) edges = [] for u in range(num_vertices): for v, weight in graph[u]: edges.append((weight, u, v)) edges.sort() mst = [] uf = UnionFind(num_vertices) for weight, u, v in edges: if uf.find(u) != uf.find(v): uf.union(u, v) mst.append((u, v, weight)) return mst ``` ### 深度优先搜索(DFS)和广度优先搜索(BFS) 对于无向连通图,可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来生成一棵生成树。从图中任意一个顶点开始,进行DFS或BFS遍历,在遍历过程中记录经过的边,这些边构成的图就是一棵生成树。以下是DFS生成树的Python示例代码: ```python def dfs_tree(graph, start): num_vertices = len(graph) visited = [False] * num_vertices tree = [] def dfs(u, parent): visited[u] = True for v in graph[u]: if not visited[v]: tree.append((u, v)) dfs(v, u) dfs(start, None) return tree ``` ### 有向图的树形图算法 对于有向图,可以使用树形图算法(如Edmonds算法)来找到一个最小树形图,即包含图中所有顶点的有向树,且树中所有边的权值之和最小。Edmonds算法的实现较为复杂,这里不给出具体代码。 ### 相关问
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值