Best Easy Solution || Easy Approach || Shriti's Solution
Intuition\n Describe your first thoughts on how to solve this problem. \n\n# Approach\n Describe your approach to solving the problem. \n\n# Complexity\n- Time 
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity:\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity:\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```cpp []\nclass Disjointset {\npublic:\n    vector<int> rank;\n    vector<int> parent;\n    vector<int> size;\n    Disjointset(int n) {\n        rank.resize(n, 0);\n        size.resize(n, 1);\n        parent.resize(n);\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n\n    int findparent(int u) {\n        if (u == parent[u]) {\n            return u;\n        }\n        return parent[u] = findparent(parent[u]);\n    }\n    void unionbyrank(int u, int v) {\n        int ulp_u = findparent(u);\n        int ulp_v = findparent(v);\n\n        if (ulp_u == ulp_v) {\n            return;\n        }\n        if (rank[ulp_u] < rank[ulp_v]) {\n            parent[ulp_u] = ulp_v;\n        } else if (rank[ulp_u] > rank[ulp_v]) {\n            parent[ulp_v] = ulp_u;\n        } else if (rank[ulp_u] == rank[ulp_v]) {\n            parent[ulp_u] = ulp_v;\n            rank[ulp_v]++;\n        }\n    }\n    void unionbysize(int u, int v) {\n        int ulp_u = findparent(u);\n        int ulp_v = findparent(v);\n\n        if (ulp_u == ulp_v) {\n            return;\n        }\n        if (size[ulp_u] < size[ulp_v]) {\n            parent[ulp_u] = ulp_v;\n            size[ulp_v] += size[ulp_u];\n        } else if (size[ulp_u] > size[ulp_v]) {\n            parent[ulp_v] = ulp_u;\n            size[ulp_u] += size[ulp_v];\n        } else if (size[ulp_u] == size[ulp_v]) {\n            parent[ulp_u] = ulp_v;\n            size[ulp_v] += size[ulp_u];\n        }\n    }\n};\n\nclass Solution {\npublic:\n    int pseudo_criticaledges(vector<vector<int>> new_edges, int index, int n) {\n        Disjointset ds2(n);\n        int totalwt = 0;\n\n        int wt = new_edges[index][0];\n        int idx = new_edges[index][1];\n        int u = new_edges[index][2];\n        int v = new_edges[index][3];\n\n        if (ds2.findparent(u) != ds2.findparent(v)) {\n            totalwt += wt;\n            ds2.unionbysize(u, v);\n        }\n\n        for (int i = 0; i < new_edges.size(); i++) {\n\n            int wt = new_edges[i][0];\n            int idx = new_edges[i][1];\n            int u = new_edges[i][2];\n            int v = new_edges[i][3];\n\n            if (ds2.findparent(u) != ds2.findparent(v)) {\n                totalwt += wt;\n                ds2.unionbysize(u, v);\n            }\n        }\n        for(int i=0; i<n; i++){\n            if(ds2.findparent(i)!=ds2.findparent(0)){\n                return INT_MAX;\n            }\n        }\n        return totalwt;\n    }\n\n    int criticaledges(vector<vector<int>> new_edges, int index, int n) {\n        Disjointset ds1(n);\n        int totalwt = 0;\n        \n        for (int i = 0; i < new_edges.size(); i++) {\n            if (i == index) {\n                continue;\n            }\n\n            int wt = new_edges[i][0];\n            int idx = new_edges[i][1];\n            int u = new_edges[i][2];\n            int v = new_edges[i][3];\n\n            if (ds1.findparent(u) != ds1.findparent(v)) {\n                totalwt += wt;\n                ds1.unionbysize(u, v);\n            }\n        }\n        for(int i=0; i<n; i++){\n            if(ds1.findparent(i)!=ds1.findparent(0)){\n                return INT_MAX;\n            }\n        }\n        return totalwt;\n    }\n    vector<vector<int>>findCriticalAndPseudoCriticalEdges(int n, vector<vector<int>>& edges) {\n        vector<vector<int>> ans;\n        vector<int> critical;\n        vector<int> pseudo_critical;\n\n        vector<vector<int>> new_edges;\n\n        for (int i = 0; i < edges.size(); i++) {\n            vector<int> temp;\n            int u = edges[i][0];\n            int v = edges[i][1];\n            int wt = edges[i][2];\n            int idx = i;\n\n            temp = {wt, i, u, v};\n\n            new_edges.push_back(temp);\n        }\n        int totalwt = 0;\n        sort(new_edges.begin(), new_edges.end());\n        Disjointset ds(n);\n        for (auto it : new_edges) {\n            int wt = it[0];\n            int idx = it[1];\n            int u = it[2];\n            int v = it[3];\n\n            if (ds.findparent(u) != ds.findparent(v)) {\n                totalwt += wt;\n                ds.unionbysize(u, v);\n            }\n        }\n        for (int i = 0; i < new_edges.size(); i++) {\n            int wt = criticaledges(new_edges, i, n);\n            int wt1 = pseudo_criticaledges(new_edges, i, n);\n\n            if (wt > totalwt) {\n                critical.push_back(new_edges[i][1]);\n            } else if (wt1 == totalwt) {\n                pseudo_critical.push_back(new_edges[i][1]);\n            }\n        }\n        ans.push_back(critical);\n        ans.push_back(pseudo_critical);\n        return ans;\n    }\n};\n```
['Union Find', 'Graph', 'Sorting', 'Minimum Spanning Tree', 'Strongly Connected Component', 'C++']