[Python] Pretty simple solution with Prim's, commented (no union find cause i'm scared of that shit)
Prim\'s is the most straightforward solution for me, since Kruskal\'s needs to maintain like union-find trees which I tend to avoid, and Beluga\'s algorithm or 
Prim\'s is the most straightforward solution for me, since Kruskal\'s needs to maintain like union-find trees which I tend to avoid, and Beluga\'s algorithm or whatever it\'s called... also needs to maintain union-find structures?  But Prim\'s is nice and prim: you only need to think of one tree that you continually grow, so all you need is a set of vertices that are in the tree, and a queue of edges-to-explore that come out of the tree.\n\n```python\nfrom heapq import heappush, heappop\n\ndef prims(n, adj, must = None):\n    """takes n, adjacency list `adj`, and optionally a (u,v,weight) edge `must`. \n\tIf `must` is given, start prim\'s with that edge and those two vertices already present.\n\tReturns the size of the MST (or a really really big number if impossible i.e. graph is disconnected)."""\n    frontier = []\n    vs = set()\n    ans = 0\n    def process_vertex(ve):\n        for edge in adj[ve]:\n            if edge[0] in vs:\n                continue\n            heappush(frontier, (edge[1], edge[0]))\n        vs.add(ve)\n    if must is not None:\n        ans += must[2]\n        process_vertex(must[0])\n        process_vertex(must[1])\n    else:\n        process_vertex(0)\n    while len(vs) < n:\n        if len(frontier) == 0:\n            return 100000000000000000\n        w, u = heappop(frontier)\n        if u in vs:\n            continue\n        ans += w\n        process_vertex(u)\n    return ans\n    \ndef make_adj(n, edges):\n    adj = [[] for i in range(n)]\n    for edge in edges:\n        u, v, w = edge\n        adj[u].append((v, w))\n        adj[v].append((u, w))\n    return adj\n\ndef remove_edge(edges, i):\n    return [edge for j, edge in enumerate(edges) if j!=i]\n\nclass Solution:\n    def findCriticalAndPseudoCriticalEdges(self, n: int, edges: List[List[int]]) -> List[List[int]]:\n\t    # first, find the size of the MST\n        adj = make_adj(n, edges)\n        minimum = prims(n, adj)\n        crit = []\n        pseu = []\n        print(minimum)\n\t\t# now, for each edge, check an MST which must use that edge, and check an MST that can\'t use that edge.\n\t\t# for each, if the size of the MST matches the size of the original MST, we know if the edge is critical and/or pseudocritical\n        for i in range(len(edges)):\n\t\t   # get size of MST that must use this edge. If as small as original, this edge is pseudocritical.\n            if prims(n, adj, edges[i]) == minimum:\n                pseu.append(i)\n\t\t\t# get size of MST on the graph that has this edge removed.  If it\'s not as small as original, this edge is critical.\n            e = remove_edge(edges, i)\n            adj_p = make_adj(n, e)\n            if prims(n, adj_p) > minimum:\n                crit.append(i)\n        return [crit, list(set(pseu) - set(crit))]\n```
['Python']