easy soluction to understand with 72% best and 96% best in space.
Intuition\nwe have to find the first MST, for compare with the nexts MST, where delete an edge and find your MST, if the next MST is diferent to first, this edg
# Intuition\nwe have to find the first MST, for compare with the nexts MST, where delete an edge and find your MST, if the next MST is diferent to first, this edge is critical.\n\n# Approach\nrun kruskal in every edge, and compare with first MST.\n\n# Complexity\n- Time complexity: O(m^2*\u03B1(n))\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity: O(n+m)\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```\nclass Solution {\npublic:\n\n    void makeSet(int node, vector<int>&father, vector<int>&range){\n\n        father[node] = node;\n        range[node] = 0;\n    }\n\n    int findSet(int node, vector<int>&father){\n\n        if(node == father[node]){\n            return node;\n        }\n\n        father[node] = findSet(father[node], father);\n        return father[node];\n    }\n\n    void unionSet(int node1, int node2, vector<int>&father, vector<int>&range){\n\n        node1 = findSet(node1,father);\n        node2 = findSet(node2, father);\n\n        if(node1 != node2){\n\n            if(range[node1] < range[node2]){\n                swap(node1, node2);\n            }\n\n            father[node2] = node1;\n\n            if(range[node1] == range[node2]){\n                range[node1]++;\n            }\n        }\n    }\n\n    int kruskal(int n, vector<vector<int>>& edges, vector<int>&father, vector<int>&range, int none, vector<int>&flag){\n\n        int i, sum = 0, node1, node2;\n\n        for(i = 0; i<edges.size(); i++){\n\n            if(i != none){\n                node1 = edges[i][0];\n                node2 = edges[i][1];\n\n                if(findSet(node1, father) != findSet(node2, father)){\n                    sum+= edges[i][2];\n                    unionSet(node1, node2, father, range);\n                }\n            }\n        }\n\n        return sum;\n    }\n\n    vector<vector<int>> findCriticalAndPseudoCriticalEdges(int n, vector<vector<int>>& edges) {\n        \n        int init, aux, i, j, ans;\n        vector<int>father(n, -1);\n        vector<int>range(n, -1);\n        vector<vector<int>>res(2);\n        vector<int>flag(edges.size(), 0);\n        for(i  = 0; i<edges.size(); i++){\n            edges[i].push_back(i);\n        }\n\n        sort(edges.begin(), edges.end(), [](vector<int>&a, vector<int>&b) {return a[2] < b[2];});\n\n        for(i = 0; i<n; i++){\n            makeSet(i, father, range);\n        }\n\n        init = kruskal(n, edges, father, range, -1, flag);\n\n        for(i  = 0; i<edges.size(); i++){\n\n            for(j = 0; j<n; j++){\n                makeSet(j, father, range);\n            }\n\n            aux = kruskal(n, edges, father, range, i, flag);\n\n            if(aux != init){\n                res[0].push_back(edges[i][3]);\n            }\n        }\n\n        for(i  = 0; i<edges.size(); i++){\n\n            for(j = 0; j<n; j++){\n                makeSet(j, father, range);\n            }\n\n            unionSet(edges[i][0], edges[i][1], father, range);\n\n            aux = kruskal(n, edges, father, range, i, flag);\n\n            if(aux + edges[i][2]== init){\n                flag[edges[i][3]] = 1;\n            }\n        }\n\n        for(i = 0; i<edges.size(); i++){\n\n            if(flag[i]){\n                cout<<i<<endl;\n                ans = 1;\n                for(j = 0; j<res[0].size() && ans; j++){\n                    if(res[0][j] == i){\n                        ans = 0;\n                    }\n                }\n\n                if(ans){\n                    res[1].push_back(i);\n                }\n            }\n        }\n        return res;\n    }\n};\n```
['C++']