Given an array of pairs arr of size N which represents a game situation where the first player wins against the second player. Given multiple queries, each query contains two numbers, the task is to determine which one of them will win if they compete with each other.
NOTE:
- If A wins over B and B wins over C, then A will always win over C.
- If A wins over B and A wins over C, if there is a match against B and C and if we couldn’t determine the winner then the player with smaller number wins
Examples:
Input : arr[] = {{0, 1}, {0, 2}, {0, 3}, {1, 5}, {2, 5}, {3, 4}, {4, 5}, {6, 0}}
query[] = {{3, 5}, {1, 2}}
Output : 5
1
Explanation : 4 wins over 3 and 5 wins over 4. So, 5 is the winner in the first match.
We can’t determine the winner between 1 and 2. So, the player with a smaller number is the winner i.e., 1Input : arr[] = {{0, 1}, {0, 2}, {0, 3}, {1, 5}, {2, 5}, {3, 4}, {4, 5}, {6, 0}}
query[] = {{0, 5}, {0, 6}}
Output : 5
0
Prerequisites: Topological Sort
Approach:
Let’s assume that all the inputs are valid. Now build a graph. If playerX wins over playerY then we add an edge from playerX to playerY. After building the graph do topological sorting. For every query of the form (x, y) we check which number x or y comes before in topological ordering and print the answer.
Below is the implementation of the above approach :
C++
// C++ program to find winner of the match #include <bits/stdc++.h> using namespace std; // Function to add edge between two nodes void add(vector< int > adj[], int u, int v) { adj[u].push_back(v); } // Function returns topological order of given graph vector< int > topo(vector< int > adj[], int n) { // Indeg vector will store // indegrees of all vertices vector< int > indeg(n, 0); for ( int i = 0; i < n; i++) { for ( auto x : adj[i]) indeg[x]++; } // Answer vector will have our // final topological order vector< int > answer; // Visited will be true if that // vertex has been visited vector< bool > visited(n, false ); // q will store the vertices // that have indegree equal to zero queue< int > q; for ( int i = 0; i < n; i++) { if (indeg[i] == 0) { q.push(i); visited[i] = true ; } } // Iterate till queue is not empty while (!q.empty()) { int u = q.front(); // Push the front of queue to answer answer.push_back(u); q.pop(); // For all neighbours of u, decrement // their indegree value for ( auto x : adj[u]) { indeg[x]--; // If indegree of any vertex becomes zero and // it is not marked then push it to queue if (indeg[x] == 0 && !visited[x]) { q.push(x); // Mark this vertex as visited visited[x] = true ; } } } // Return the resultant topological order return answer; } // Function to return the winner between u and v int who_wins(vector< int > topotable, int u, int v) { // Player who comes first wins for ( auto x : topotable) { if (x == u) return u; if (x == v) return v; } } // Driver code int main() { vector< int > adj[10]; // Total number of players int n = 7; // Build the graph // add(adj, x, y) means x wins over y add(adj, 0, 1); add(adj, 0, 2); add(adj, 0, 3); add(adj, 1, 5); add(adj, 2, 5); add(adj, 3, 4); add(adj, 4, 5); add(adj, 6, 0); // Resultant topological order in topotable vector< int > topotable = topo(adj, n); // Queries cout << who_wins(topotable, 3, 5) << endl; cout << who_wins(topotable, 1, 2) << endl; return 0; } |
Python3
# Python3 program to find winner of the match # Function to add edge between two nodes def add(adj, u, v): adj[u].append(v) # Function returns topological order of given graph def topo(adj, n): # Indeg vector will store # indegrees of all vertices indeg = [ 0 for i in range (n)] for i in range (n): for x in adj[i]: indeg[x] + = 1 # Answer vector will have our # final topological order answer = [] # Visited will be true if that # vertex has been visited visited = [ False for i in range (n)] # q will store the vertices # that have indegree equal to zero q = [] for i in range (n): if (indeg[i] = = 0 ): q.append(i) visited[i] = True # Iterate till queue is not empty while ( len (q) ! = 0 ): u = q[ 0 ] # Push the front of queue to answer answer.append(u) q.remove(q[ 0 ]) # For all neighbours of u, decrement # their indegree value for x in adj[u]: indeg[x] - = 1 # If indegree of any vertex becomes zero and # it is not marked then push it to queue if (indeg[x] = = 0 and visited[x] = = False ): q.append(x) # Mark this vertex as visited visited[x] = True # Return the resultant topological order return answer # Function to return the winner between u and v def who_wins(topotable, u, v): # Player who comes first wins for x in topotable: if (x = = u): return u if (x = = v): return v # Driver code if __name__ = = '__main__' : adj = [[] for i in range ( 10 )] # Total number of players n = 7 # Build the graph # add(adj, x, y) means x wins over y add(adj, 0 , 1 ) add(adj, 0 , 2 ) add(adj, 0 , 3 ) add(adj, 1 , 5 ) add(adj, 2 , 5 ) add(adj, 3 , 4 ) add(adj, 4 , 5 ) add(adj, 6 , 0 ) # Resultant topological order in topotable topotable = topo(adj, n) # Queries print (who_wins(topotable, 3 , 5 )) print (who_wins(topotable, 1 , 2 )) # This code is contributed by Surendra_Gangwar |
3 1
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.