You are given an undirected graph with ‘N’ nodes and ‘M’ edges. There are two players P1 and P2, who want to traverse the complete graph. There are three types of edges in the graph, type 1 edges can be traversed by player P1, type 2 edges can be traversed by player P2, and type 3 edges can be traversed by both P1 and P2.
You are supposed to find the maximum number of edges that can be removed from the graph so that both players P1 and P2 can reach any node of the graph.
For Example :
In the above graph, we can remove both the edges connecting node 1 and node 2(of type 1 and type 2). The graph will be fully traversable by only type 3 edges.
The first line contains a single integer ‘T’ denoting the number of test cases. The test cases are as follows.
The first line of each test case contains two integers separated by a single space ‘N’ and ‘M’ denoting the number of the nodes and the number of edges respectively.
The next ‘M’ lines of each test case contain three integers “TYPE”, ‘X’ and ‘Y’ separated by a single space, here “TYPE” denotes the type of edge and ‘X’ and ’Y’ denote the vertices connected by an edge.
Output Format :
For each test case, print the maximum number of edges that can be removed such that the graph is fully traversable by both P1 and P2 after removing the edges. If the graph cannot be fully traversed by P1 or P2 return -1.
Print the output of each test case on a new line.
Note :
You don’t need to print anything; It has already been taken care of. Just implement the given function.
1 <= T <= 5
1 <= N <= 10^5
1 <= M <= 10^5
1 <= TYPE <= 3
1 <= X,Y <= N
Where ‘T’ denotes the number of test cases, ‘N’ denotes the number of nodes in the graph, ‘M’ denotes the number of edges in the graph, “TYPE” denotes the type of edge, ‘X’ and ‘Y’ denote the nodes of the graph.
Time Limit: 1 sec
2
4 5
1 1 2
2 1 2
3 4 1
3 2 4
3 3 4
3 3
3 1 2
2 2 3
1 1 3
2
0
In the first test case, we can remove 2 edges connecting node 1 and node 2(refer to the example above).
In the second test case, we cannot remove any edge as removing any edge will make the graph disconnected.
2
4 2
1 2 1
3 3 4
2 2
3 1 2
1 2 1
-1
1
In the first test case, the graph is disconnected hence both the players cannot traverse all the nodes.
In the second test case, we can remove one edge of type 1.
Can you think about which type of edges should be traversed first?
Suppose there are 3 edges from node 1 to node 2 of types 1,2 and 3. Now if both P1 and P2 are at node 1 and want to go to node 2, we can see that if both of them traverse the edge of type 3 then we can remove edges of type 1 and type 2, otherwise, we can remove at max 1 edge from node1 and node 2. From this observation, we can conclude that it is always optimal to traverse type 3 edges before traversing any other type of edge.
The idea is to use the Disjoint Set Union(also known as Union Find) data structure and traverse the type 3 edges before traversing edges of type 2 and type 1. Initially, we will start with an empty graph and we will merge all connected nodes into a single component and keep track of the number of edges we are including to keep the graph connected.
The steps are as follows :
O(M*N), where ‘N’ is the number of nodes and ‘M’ is the number of edges in the graph.
We are iterating through all the edges and then finding the parent nodes for both nodes of each edge. There are ‘M’ edges and finding the parent node for each node can take O(N) time in the worst case when the graph forms a long chain-like structure. Thus, the overall time complexity is O(M*N).
O(N), where N is the number of nodes in the graph.
We are creating adjacency lists for storing type 1 and type 2 edges which will take O(N) space. Thus, the overall space complexity is O(N).