q.append(first_node)
        visited.add(first_node)

        while q:
            node = q.popleft()
            print(node, end=" ")

            for elem, connection in enumerate(g[node]):
                if elem not in visited and connection and connection < math.inf:
                    q.append(elem)
                    visited.add(elem)


if __name__ == "__main__":
    g = GraphM(4)
    g.add_edge(0, 1)
    g.add_edge(0, 2)
    g.add_edge(1, 2)
    g.add_edge(2, 0)
    g.add_edge(2, 3)
    g.add_edge(3, 3)
    print("bfs starting at node 2")
    breadth_first_travel(g.graph, 2)
    print()
    print("bfs starting at node 1")
    breadth_first_travel(g.graph, 1)
    print()
    print("bfs starting at node 0")
    breadth_first_travel(g.graph, 0)
    print()
    print("bfs starting at node 3")
        path.pop(-1)
        return total

    path: list = [source]

    for source, distance in enumerate(graph[source]):
        if 0 < distance < math.inf and backtrack(source, distance, {source},
                                                 0) > k:
            return path

    return []


if __name__ == "__main__":
    g = GraphM(9)
    g.add_edge(0, 1, 4)
    g.add_edge(0, 7, 8)
    g.add_edge(1, 2, 8)
    g.add_edge(1, 7, 11)
    g.add_edge(2, 3, 7)
    g.add_edge(2, 5, 4)
    g.add_edge(2, 8, 2)
    g.add_edge(3, 4, 9)
    g.add_edge(3, 5, 14)
    g.add_edge(4, 5, 10)
    g.add_edge(5, 6, 2)
    g.add_edge(6, 7, 1)
    g.add_edge(6, 8, 6)
    g.add_edge(7, 8, 7)

    print(path_greater(g.graph, 0, 60, g.num_vertices))
    """

    visited = set()
    graph_list = graph.graph
    mother = None

    for vertex in range(graph.num_vertices):
        if vertex not in visited:
            visited = dfs(graph_list, vertex, visited)
            mother = vertex

    visited = set()
    dfs(graph_list, mother, visited)  # check if all others can reach from here

    if any(vertex not in visited for vertex in range(graph.num_vertices)):
        return None
    return mother


if __name__ == "__main__":
    g = GraphM(7, "directed")
    g.add_edge(0, 2)
    g.add_edge(1, 3)
    g.add_edge(0, 1)
    g.add_edge(4, 1)
    g.add_edge(6, 4)
    g.add_edge(5, 6)
    g.add_edge(5, 2)
    g.add_edge(6, 0)
    print("A mother vertex is", get_mother_vertex(g))
Exemple #4
0
        All nodes with less in-degree can safely add an edge
        to all nodes with degrees less than them.
        For nodes with same in-degree, we can safely add a directed node in one direction.
    Solution from Kahn's algorithm can be used here
    time complexity: O(V+E)
    """
    sorted_vertices = topological_sort_kahn_algorithm(graph, vertices)
    res: list = []
    visited: set = set()

    for src in sorted_vertices:
        for dest, connected in enumerate(graph[src]):
            if connected not in (0, 1) and dest not in visited:
                res.append((src, dest))
                graph[src][dest] = 1
        visited.add(src)

    return res, len(res)


if __name__ == "__main__":
    g = GraphM(6, "directed")
    g.add_edge(4, 0)
    g.add_edge(4, 1)
    g.add_edge(5, 2)
    g.add_edge(5, 0)
    g.add_edge(2, 3)
    g.add_edge(3, 1)

    print(*add_edges_safely(g.graph, g.num_vertices))

def is_cyclic(graph: list, vertices: int) -> bool:
    subsets: list = [Subset(v, 0) for v in range(vertices)]

    for u in range(vertices):
        pu = find(u, subsets)

        for v, connection in enumerate(graph[u]):
            if u != v and connection == 1:
                pv = find(v, subsets)

                if pu == pv:
                    return True
                union(pu, pv, subsets)

    return False


if __name__ == "__main__":
    g = GraphM(3)
    g.add_edge(0, 1)
    g.add_edge(1, 2)
    g.add_edge(0, 2)

    if is_cyclic(g.graph, g.num_vertices):
        print("Graph contains cycle")
    else:
        print("Graph does not contain cycle")

        ts_list.append(element)
        visited.add(element)

        for vertex, connected in enumerate(graph[element]):
            if connected == 1:
                indegree_list[vertex] -= 1

                if indegree_list[vertex] == 0:
                    queue.append(vertex)

    return ts_list if len(visited) == len(graph) else []


if __name__ == "__main__":
    g = GraphM(7, "directed")
    g.add_edge(0, 2)
    g.add_edge(1, 2)
    g.add_edge(1, 3)
    g.add_edge(2, 4)
    g.add_edge(3, 5)
    g.add_edge(4, 5)
    g.add_edge(5, 6)

    print(topological_sort_using_dfs(g.graph, g.num_vertices))
    print(topological_sort_kahn_algorithm(g.graph, g.num_vertices))

    g = GraphM(6, "directed")
    g.add_edge(5, 0)
    g.add_edge(5, 2)
    g.add_edge(2, 3)
    g.add_edge(3, 1)
                        gray_stack.append(neighbor)
                        gray_set.add(neighbor)
                        initial_set.remove(neighbor)

            if not found:  # if sub-graph is completely explored, move the node to processed
                gray_set.remove(cur_node)
                processed_set.add(cur_node)
        else:
            cur_node = initial_set.pop()
            gray_set.add(cur_node)
            gray_stack.append(cur_node)


if __name__ == "__main__":
    g = GraphM(4, "directed")
    g.add_edge(0, 1)
    g.add_edge(0, 2)
    g.add_edge(1, 2)
    g.add_edge(2, 0)
    g.add_edge(2, 3)
    g.add_edge(3, 3)

    print("First Graph")
    for i in range(g.num_vertices):
        print(g.graph[i])

    detect_print_cycle(g.graph, g.num_vertices)
    detect_cycle_dfs(g.graph, g.num_vertices)

    g = GraphM(6, "directed")
    g.add_edge(0, 1)