Clean Code || Easy to understand || Union Find
A BIT OF REDUNDANT CODE \uD83D\uDE05, JUST FOR SIMPLICITY\n### ALSO INCLUDED A \'NOT REDUNDANT\' CODE LATER \uD83D\uDC47\uD83D\uDC47\n\nclass Solution {\npublic
### A BIT OF REDUNDANT CODE \uD83D\uDE05, JUST FOR SIMPLICITY\n### ALSO INCLUDED A \'NOT REDUNDANT\' CODE LATER \uD83D\uDC47\uD83D\uDC47\n```\nclass Solution {\npublic:\n    int findParent(vector<int>&parent, int node)\n    {\n        if (parent[node] == node) return node;\n        else return findParent(parent, parent[node]);\n    }\n    bool merge(vector<int>&parent, vector<int>&rank, int node1, int node2)\n    {\n        int parent1 = findParent(parent, node1);\n        int parent2 = findParent(parent, node2);\n        if (parent1 == parent2) return false;\n        else\n        {\n            //NON-OPTIMAL WAY => { parent[parent1] = parent2 or parent[parent2] = parent2; return; :)} \n            //OPTIMAL WAY=> merge based on rank to reduce complexity in \'FINDING PARENT\' next time\n            if (rank[parent1] == rank[parent2])  //both at same level\n            {\n                parent[parent1] = parent2; \n                rank[parent2]++; \n            }\n            else if (rank[parent1] < rank[parent2]) //parent2 is at higher level\n                parent[parent1] = parent2; \n            else  //parent1 is at higher level\n                parent[parent2] = parent1;\n            return true;\n        }\n    }\n    int maxNumEdgesToRemove(int n, vector<vector<int>>& edges) \n    {\n        int notUsed = 0, componentCount = n;\n        vector<int>parent(n + 1);\n        vector<int>rank(n + 1, 0);\n        for (int i = 1; i <= n; i++) parent[i] = i;\n        //===========================================================================\n        //COMMON FOR BOTH\n        for (vector<int>&edge : edges)\n        {\n            if (edge[0] != 3) continue;\n            \n            bool merged = merge(parent, rank, edge[1], edge[2]);\n            if (!merged) notUsed++;\n            else componentCount--;\n        }\n        //===========================================================================\n        //ONLY FOR ALICE\n        vector<int>aliceParent = parent, aliceRank = rank;\n        int aliceComponentCount = componentCount;\n        for (vector<int>&edge : edges)\n        {\n            if (edge[0] != 1) continue;\n            bool merged = merge(aliceParent, aliceRank, edge[1], edge[2]);\n            if (!merged) notUsed++;\n            else aliceComponentCount--;\n        }\n        if (aliceComponentCount != 1) return -1;  //still not connected, so return -1\n        //==============================================================================\n        //ONLY FOR BOB\n        //could have used tha main \'parent\', \'rank\', \'componentCount\'...\n        //made duplicate copies here also only to explain \n        vector<int>bobParent = parent, bobRank = rank; \n        int bobComponentCount = componentCount;\n        for (vector<int>&edge : edges)\n        {\n            if (edge[0] != 2) continue;\n            bool merged = merge(bobParent, bobRank, edge[1], edge[2]);\n            if (!merged) notUsed++;\n            else bobComponentCount--;\n        }\n        if (bobComponentCount != 1) return -1;  //still not connected, so return -1\n        //================================================================================\n        return notUsed;//not used edges will be removed\n        \n    }\n};\n```\n//=======================================================================================================================\n## REDUCED DUPLICACY\n```\nclass Solution {\npublic:\n    int notUsed = 0;\n    int findParent(vector<int>&parent, int node)\n    {\n        if (parent[node] == node) return node;\n        else return findParent(parent, parent[node]);\n    }\n    bool merge(vector<int>&parent, vector<int>&rank, int node1, int node2)\n    {\n        int parent1 = findParent(parent, node1);\n        int parent2 = findParent(parent, node2);\n        if (parent1 == parent2) return false;\n        else\n        {\n            if (rank[parent1] == rank[parent2])  //both at same level\n            {\n                parent[parent1] = parent2; \n                rank[parent2]++; \n            }\n            else if (rank[parent1] < rank[parent2]) //parent2 is at higher level\n                parent[parent1] = parent2; \n            else  //parent1 is at higher level\n                parent[parent2] = parent1;\n            return true;\n        }\n    }\n    void solve(vector<vector<int>>&edges, vector<int>&parent, vector<int>&rank, int& componentCount, int currType)\n    {\n        for (vector<int>&edge : edges)\n        {\n            if (edge[0] != currType) continue;\n            \n            bool merged = merge(parent, rank, edge[1], edge[2]);\n            if (!merged) notUsed++; //declared global\n            else componentCount--;\n        }\n    }\n    int maxNumEdgesToRemove(int n, vector<vector<int>>& edges) \n    {\n        //==============================================================================\n        //COMMON FOR BOTH\n        int componentCount = n;\n        vector<int>parent(n + 1);\n        vector<int>rank(n + 1, 0);\n        for (int i = 1; i <= n; i++) parent[i] = i;\n        solve(edges, parent, rank, componentCount, 3);\n        //===============================================================================\n        //ONLY FOR ALICE\n        vector<int>aliceParent = parent, aliceRank = rank;\n        int aliceComponentCount = componentCount;\n        solve(edges, aliceParent, aliceRank, aliceComponentCount, 1);\n        if (aliceComponentCount != 1) return -1;  \n        //==============================================================================\n        //ONLY FOR BOB\n        vector<int>bobParent = parent, bobRank = rank; \n        int bobComponentCount = componentCount;\n        solve(edges, bobParent, bobRank, bobComponentCount, 2);\n        if (bobComponentCount != 1) return -1;  \n        //================================================================================\n        return notUsed;//not used edges will be removed\n        \n    }\n};\n```\n
['Union Find', 'C', 'C++']