C++ || DSU || Explained || Striver's Approach
\nclass DisjointSet {\n    \npublic: \n    vector<int> rank, parent, size; \n    // rank: array to store rank of each set\n    // parent: array to store parent 
```\nclass DisjointSet {\n    \npublic: \n    vector<int> rank, parent, size; \n    // rank: array to store rank of each set\n    // parent: array to store parent of each node\n    // size: array to store size of each set\n    DisjointSet(int n) {\n        rank.resize(n+1, 0); \n        parent.resize(n+1);\n        size.resize(n+1); \n        // initialize each node as a parent of itself\n        // and the size of each set as 1\n        for(int i = 0;i<=n;i++) {\n            parent[i] = i; \n            size[i] = 1; \n        }\n    }\n\n    int findUPar(int node) {\n        // find the ultimate parent of the given node\n        // using path compression\n        if(node == parent[node])\n            return node; \n        return parent[node] = findUPar(parent[node]); \n    }\n\n    void unionByRank(int u, int v) {\n        // union two sets based on their rank\n        int ulp_u = findUPar(u); \n        int ulp_v = findUPar(v); \n        if(ulp_u == ulp_v) return; \n        if(rank[ulp_u] < rank[ulp_v]) {\n            parent[ulp_u] = ulp_v; \n        }\n        else if(rank[ulp_v] < rank[ulp_u]) {\n            parent[ulp_v] = ulp_u; \n        }\n        else {\n            parent[ulp_v] = ulp_u; \n            rank[ulp_u]++; \n        }\n    }\n\n    void unionBySize(int u, int v) {\n        // union two sets based on their size\n        int ulp_u = findUPar(u); \n        int ulp_v = findUPar(v); \n        if(ulp_u == ulp_v) return; \n        if(size[ulp_u] < size[ulp_v]) {\n            parent[ulp_u] = ulp_v; \n            size[ulp_v] += size[ulp_u]; \n        }\n        else {\n            parent[ulp_v] = ulp_u;\n            size[ulp_u] += size[ulp_v]; \n        }\n    }\n};\n\nclass Solution {\npublic:\n    int makeConnected(int n, vector<vector<int>>& adj) {\n        DisjointSet ds(n); // create a disjoint set object\n        int extra=0; // count the number of extra edges\n        for(auto it: adj){\n            int u=it[0];\n            int v=it[1];\n\n            if(ds.findUPar(u)==ds.findUPar(v)){\n                extra++;\n            }\n            else{\n                ds.unionBySize(u,v); // union two sets\n            }\n        }\n\n        int ans=0; // count the number of connected components\n        for(int i=0;i<n;i++){\n            if(ds.parent[i]==i)\n            ans++;\n        }\n        ans=ans-1; // subtract 1 from the count to get the number of cables required\n        if(extra>=ans)\n        return ans; // if we have enough extra cables to connect all the components, return the answer\n\n        return -1; // otherwise, it\'s impossible to connect all the components\n    }\n}; \n\n```
[]