Open In App

Find the winner of the match | Multiple Queries

Improve
Improve
Like Article
Like
Save
Share
Report

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 : 3

Explanation : 3 wins over 4 and 4 wins over 5. So, 3 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., 1
Input : arr[] = {{0, 1}, {0, 2}, {0, 3}, {1, 5}, {2, 5}, {3, 4}, {4, 5}, {6, 0}} 
query[] = {{0, 5}, {0, 6}} 
Output : 0
6
 

 

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;
}


Java




/*package whatever //do not write package name here */
import java.util.*;
 
public class GFG{
  // Function to add edge between two nodes
  static void add(List<Integer> adj[], int u, int v)
  {
    adj[u].add(v);
  }
 
  // Function returns topological order of given graph
  static List<Integer> topo(List<Integer> adj[], int n)
  {
     
    // Indeg vector will store
    // indegrees of all vertices
    int []indeg = new int[n];
    for (int i = 0; i < n; i++) {
      for (int x : adj[i])
        indeg[x]++;
    }
    // Answer vector will have our
    // final topological order
    List<Integer> answer = new ArrayList<Integer>();
 
    // Visited will be true if that
    // vertex has been visited
    boolean[] visited = new boolean[n];
 
    // q will store the vertices
    // that have indegree equal to zero
    Queue<Integer> q = new PriorityQueue<>();
    for (int i = 0; i < n; i++) {
      if (indeg[i] == 0) {
        q.add(i);
        visited[i] = true;
      }
    }
 
    // Iterate till queue is not empty
    while (!q.isEmpty()) {
      int u = q.peek();
      // Push the front of queue to answer
      answer.add(u);
      q.poll();
 
      // For all neighbours of u, decrement
      // their indegree value
      for (int 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.add(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
  static int who_wins(List<Integer> topotable, int u, int v)
  {
    // Player who comes first wins
    for (int x : topotable) {
      if (x == u)
        return u;
      if (x == v)
        return v;
    }
    return 0;
  }
  public static void main(String[] args) {
 
    List<Integer> adj[] = new ArrayList[10];
 
    for (int i = 0; i < 10; i++) {
      adj[i] = new ArrayList<Integer>();
    }
    // 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
    List<Integer> topotable = topo(adj, n);
 
    // Queries
    System.out.println(who_wins(topotable, 3, 5));
    System.out.println(who_wins(topotable, 1, 2));
 
  }
}
 
// This code is contributed by aadityaburujwale.


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


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class GFG {
    // Function to add edge between two nodes
    static void add(List<int>[] adj, int u, int v)
    {
        adj[u].Add(v);
    }
 
    // Function returns topological order of given graph
    static List<int> topo(List<int>[] adj, int n)
    {
 
        // Indeg vector will store
        // indegrees of all vertices
        int[] indeg = new int[n];
        for (int i = 0; i < n; i++) {
            foreach(int x in adj[i]) indeg[x]++;
        }
        // Answer vector will have our
        // final topological order
        List<int> answer = new List<int>();
 
        // Visited will be true if that
        // vertex has been visited
        bool[] visited = new bool[n];
 
        // q will store the vertices
        // that have indegree equal to zero
        Queue<int> q = new Queue<int>();
        for (int i = 0; i < n; i++) {
            if (indeg[i] == 0) {
                q.Enqueue(i);
                visited[i] = true;
            }
        }
 
        // Iterate till queue is not empty
        while (q.Count() != 0) {
            int u = q.Peek();
            // Push the front of queue to answer
            answer.Add(u);
            q.Dequeue();
 
            // For all neighbours of u, decrement
            // their indegree value
            foreach(int x in 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.Enqueue(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
    static int who_wins(List<int> topotable, int u, int v)
    {
        // Player who comes first wins
        foreach(int x in topotable)
        {
            if (x == u)
                return u;
            if (x == v)
                return v;
        }
        return 0;
    }
    public static void Main(string[] args)
    {
 
        List<int>[] adj = new List<int>[ 10 ];
 
        for (int i = 0; i < 10; i++) {
            adj[i] = new List<int>();
        }
        // 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
        List<int> topotable = topo(adj, n);
 
        // Queries
        Console.WriteLine(who_wins(topotable, 3, 5));
        Console.WriteLine(who_wins(topotable, 1, 2));
    }
}
 
// This code is contributed by akashish__


Javascript




<script>
 
brbr// JavaScript program to find winner of the match
 
// Function to add edge between two nodes
function add(adj, u, v){
    adj[u].push(v)
}
 
// Function returns topological order of given graph
function topo(adj, n){
 
    // Indeg vector will store
    // indegrees of all vertices
    let indeg = new Array(n).fill(0)
    for(let i=0;i<n;i++){
        for(let x of adj[i]){
            indeg[x] += 1
        }
    }
 
    // Answer vector will have our
    // final topological order
    let answer = []
 
    // Visited will be true if that
    // vertex has been visited
    let visited = new Array(n).fill(false)
 
    // q will store the vertices
    // that have indegree equal to zero
    let q = []
    for(let i=0;i<n;i++){
        if (indeg[i] == 0){
            q.push(i)
            visited[i] = true
        }
    }
 
    // Iterate till queue is not empty
    while (q.length != 0){
        let u = q.shift()
 
        // Push the front of queue to answer
        answer.push(u)
 
        // For all neighbours of u, decrement
        // their indegree value
        for(let x of 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 && visited[x] == false){
                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
function who_wins(topotable, u, v){
    // Player who comes first wins
    for(let x of topotable){
        if (x == u)
            return u
        if (x == v)
            return v
    }
}
 
// Driver code
  
let adj = new Array(10).fill(0).map(()=>new Array())
 
// Total number of players
let 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
let topotable = topo(adj, n)
 
// Queries
document.write(who_wins(topotable, 3, 5),"</br>")
document.write(who_wins(topotable, 1, 2),"</br>")
 
// This code is contributed by shinjanpatra
 
</script>


Output: 

3
1

 

Time Complexity: O(V+E), where V is the number of vertices and E is the number of edges in the graph.

Auxiliary space: O(V+E)



Last Updated : 22 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads