C++ Understandable Solution Walkthrough. T.C : O(EV) Based On MST
A DSU Class Where Both The Functions Are Implemented in Their Best State\n\n    The findParent() Has A Time Complexity Amortized To O(1) from O(logN)\n    Using
**A DSU Class Where Both The Functions Are Implemented in Their Best State**\n\n    The findParent() Has A Time Complexity Amortized To O(1) from O(logN)\n    Using Path Compression.\n  \n    The Union Function Used The Method Of Size Compression To Balance The Height Of\n    The Tree.  \n    \n    Sort The Edges According To Their Weight Which Has A Time Complexity Of O(ElogE)\n    Using An Appropriate Comparator Function\n    \n    Create The Minimum Spanning Tree Using Kruskal\'s Algo\n    \n*     CRITICAL EDGE :\n    Now For Critical Edge We Run Through A Brute Force Approach Of Excluding A Single Edge\n    And Forming The Minimum Spanning Tree\n    \n    **If The Cost Of It Is Greater Than The Cost Of The Initially Formed MST, Then It Is\n    Definitely A Critical Edge**\n\n    **Another Case Is Possible Where The Cost Comes To Be Less Than Cost Of MST, Which Is\n        Impossible In Sense. Hence It Means Without That Edge The MST Cant Be Formed**\n        So This Is Also A Critical Edge.\n\n\t*****Mind That There Can Be Edges Which Are Not Considered In The MST.\n    This Is Handled In The Pseudo Critical Edge List    \n   \n*    PSEUDO CRITICAL EDGE :\n   Now We Forcefully Include The Edges Which Are Not There In The Critical Edges.\n    \n    After That We Check Whether The Cost Is Same As That Of MST Or Not.\n    If Equal Then It Is A Pseudo Critical Edge Else Not.\n\t\n\tTime Complexity : O(ElogE)+ O(EV) + O(EV) ~O(EV)\n\tSpace Complexity : O(E+V)\n\t\n```\nclass Solution {\npublic:\n\nclass DSU\n{\n    public:\n    int findParent(int node,vector<int>& par)\n    {\n        if(par[node]==node)return node;\n        return par[node]=findParent(par[node],par);\n    }\n    void Union(int u,int v,vector<int> &size,vector<int> &par)\n    {\n        int pu=findParent(u,par);\n        int pv=findParent(v,par);\n        if(pu==pv)return;\n        if(size[pu]<=size[pv])\n        {\n            par[pu]=pv;\n            size[pv]++;\n        }\n        else\n        {\n            par[pv]=pu;\n            size[pu]++;\n        }\n    }\n};\n    \n    static bool comp(vector<int> &v1,vector<int> &v2)\n    {\n        return v1[2]<v2[2];        \n    }\n    vector<vector<int>> findCriticalAndPseudoCriticalEdges(int n, vector<vector<int>>& edges) \n    {\n        int len=edges.size();\n        for(int i=0;i<len;i++)\n            edges[i].push_back(i);\n  \n        sort(edges.begin(),edges.end(),comp);\n \n        DSU dsu;\n        int cost=0;\n        vector<int> par(n);\n        vector<int> size(n,1);\n        for(int i=0;i<n;i++)par[i]=i;\n        vector<bool> isPart(len,0);\n        // First MST\n        int c=0;\n        for(int i=0;i<len;i++)\n        {   \n            if(c==n-1)break;\n            if(dsu.findParent(edges[i][0],par)!=dsu.findParent(edges[i][1],par))\n            {   \n                dsu.Union(edges[i][0],edges[i][1],size,par);\n                isPart[edges[i][3]]=1;\n                cost+=edges[i][2];\n                ++c;\n            }\n        }\n        vector<int> critical,pseudocritical;\n        // Critical Edge Find\n        for(int i=0;i<len;i++)\n        {\n            DSU tempDSU;\n            vector<int> tempPar(n,0);\n            for(int j=0;j<n;j++)tempPar[j]=j;\n            \n            vector<int> tempSize(n,1);\n            int tempCost=0;\n            vector<bool> temp(len,0);\n            int c=0;\n            for(int j=0;j<len;j++)\n            {   \n                if(c==n-1)break;\n                //Create New MST Excluding ith Edge\n                if(j==i)continue;               \n                if(tempDSU.findParent(edges[j][0],tempPar)!=tempDSU.findParent(edges[j][1],tempPar))\n                {\n                    tempDSU.Union(edges[j][0],edges[j][1],tempSize,tempPar);\n                    temp[edges[j][3]]=1;\n                    tempCost+=edges[j][2];\n                    c++;\n                }\n            }\n            if(tempCost==cost)\n            {\n                for(int k=0;k<len;k++)\n                {\n                    if(temp[k])isPart[k]=1;\n                }    \n            }\n            else\n                critical.push_back(edges[i][3]);\n        }\n        \n        for(int i=0;i<len;i++)\n        {\n            if(isPart[edges[i][3]])continue;\n            DSU tempDSU;\n            vector<int> tempPar(n,0);\n            for(int j=0;j<n;j++)tempPar[j]=j;\n            vector<int> tempSize(n,1);\n            int tempCost=0;\n            tempDSU.Union(edges[i][0],edges[i][1],tempSize,tempPar);\n            tempCost+=edges[i][2];\n            int c=0;\n            for(int j=0;j<len;j++)\n            {   //Create New MST Excluding This Edge\n                if(c==n-1)break;\n                if(j==i)continue;               \n                if(tempDSU.findParent(edges[j][0],tempPar)!=tempDSU.findParent(edges[j][1],tempPar))\n                {\n                    tempDSU.Union(edges[j][0],edges[j][1],tempSize,tempPar);\n                    tempCost+=edges[j][2];\n                    ++c;\n                }\n            }\n            if(tempCost==cost)\n                pseudocritical.push_back(edges[i][3]);\n        }\n        for(auto &it : critical)\n            isPart[it]=0;\n        for(int i=0;i<len;i++)\n        {\n            if(isPart[i])\n                pseudocritical.push_back(i);\n        }\n        return {critical,pseudocritical};\n    }\n};\n```\n
['Union Find', 'C']