Find the winner of the match | Multiple Queries

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., 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 : 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 :

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


Output:

3
1


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.