Beats 98% | Self Explanatory with comments | C++ code
\nclass DSU{\nprivate:\n    vector<int> par, size;\npublic:\n    DSU(int n){\n        par = vector<int>(n+1);\n        size = vector<int>(n+1);\n        for(int
```\nclass DSU{\nprivate:\n    vector<int> par, size;\npublic:\n    DSU(int n){\n        par = vector<int>(n+1);\n        size = vector<int>(n+1);\n        for(int i=0; i<=n; i++){\n            par[i] = i;\n        }\n    }\n    \n    bool merge(int a, int b){\n        a = find(a);\n        b = find(b);\n        if(a == b) \n            return false;\n        if(size[a] < size[b]){\n            swap(a, b);\n        }\n        par[b] = a;\n        return true;\n    }\n    \n    int find(int node){\n        if(par[node] == node){\n            return node;\n        }\n        return par[node] = find(par[node]);\n    }\n    \n    void reset(){\n        for(int i=0; i<par.size(); i++){\n            par[i] = i;\n            size[i] = 1;\n        }\n    }\n};\n\nclass Solution {\npublic:\n    int getMstVal(DSU &d, vector<vector<int>>& edges, int n, int skip){\n        int mstVal = 0;\n        for(int i=0; i<edges.size(); i++){\n            if(i == skip) continue;\n            if(d.merge(edges[i][0], edges[i][1])){\n                mstVal += edges[i][2];\n                if(--n == 0){\n                    return mstVal;      \n                }\n            }\n        }\n        return -1;     //invalid value to respresent disconnected tree\n    }\n    \n    vector<vector<int>> findCriticalAndPseudoCriticalEdges(int n, vector<vector<int>>& edges) {\n        //find actual mst value\n        \n        // I will not use this edge and find mst value to compare\n        // If it\'s same, it means it\'s not a critical\n        // else it\'s critical\n        \n        //I will forcefully use this edge, and find mst value to compare\n        //If it\'s same, it\'s psuedo critical\n        //else not\n        \n        \n        // To keep original index of each edge\n        int orgIndex = 0;\n        for(auto &edge:edges){\n            edge.push_back(orgIndex++);\n        }\n        \n        sort(edges.begin(), edges.end(), [](vector<int> &a, vector<int> &b){\n            return a[2]<b[2];\n        });\n        \n        DSU d(n);\n        int actualMst = getMstVal(d, edges, n - 1, -1);\n        vector<vector<int>> ans(2);\n        for(int i=0; i<edges.size(); i++) {\n            d.reset();\n            int curMst = getMstVal(d, edges, n - 1, i);\n            if(curMst != actualMst){\n                ans[0].push_back(edges[i][3]);\n                continue;\n            }\n            \n            d.reset();\n            d.merge(edges[i][0], edges[i][1]);\n            curMst = edges[i][2] + getMstVal(d, edges, n - 2, -1);\n            if(curMst == actualMst){\n                ans[1].push_back(edges[i][3]);\n                continue;\n            }\n        }\n        return ans;\n    }\n};\n```
[]