Find the winner of the match | Multiple Queries
Last Updated :
22 Feb, 2023
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
1
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++
#include <bits/stdc++.h>
using namespace std;
void add(vector< int > adj[], int u, int v)
{
adj[u].push_back(v);
}
vector< int > topo(vector< int > adj[], int n)
{
vector< int > indeg(n, 0);
for ( int i = 0; i < n; i++) {
for ( auto x : adj[i])
indeg[x]++;
}
vector< int > answer;
vector< bool > visited(n, false );
queue< int > q;
for ( int i = 0; i < n; i++) {
if (indeg[i] == 0) {
q.push(i);
visited[i] = true ;
}
}
while (!q.empty()) {
int u = q.front();
answer.push_back(u);
q.pop();
for ( auto x : adj[u]) {
indeg[x]--;
if (indeg[x] == 0 && !visited[x]) {
q.push(x);
visited[x] = true ;
}
}
}
return answer;
}
int who_wins(vector< int > topotable, int u, int v)
{
for ( auto x : topotable) {
if (x == u)
return u;
if (x == v)
return v;
}
}
int main()
{
vector< int > adj[10];
int n = 7;
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);
vector< int > topotable = topo(adj, n);
cout << who_wins(topotable, 3, 5) << endl;
cout << who_wins(topotable, 1, 2) << endl;
return 0;
}
|
Java
import java.util.*;
public class GFG{
static void add(List<Integer> adj[], int u, int v)
{
adj[u].add(v);
}
static List<Integer> topo(List<Integer> adj[], int n)
{
int []indeg = new int [n];
for ( int i = 0 ; i < n; i++) {
for ( int x : adj[i])
indeg[x]++;
}
List<Integer> answer = new ArrayList<Integer>();
boolean [] visited = new boolean [n];
Queue<Integer> q = new PriorityQueue<>();
for ( int i = 0 ; i < n; i++) {
if (indeg[i] == 0 ) {
q.add(i);
visited[i] = true ;
}
}
while (!q.isEmpty()) {
int u = q.peek();
answer.add(u);
q.poll();
for ( int x : adj[u]) {
indeg[x]--;
if (indeg[x] == 0 && !visited[x]) {
q.add(x);
visited[x] = true ;
}
}
}
return answer;
}
static int who_wins(List<Integer> topotable, int u, int v)
{
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>();
}
int n = 7 ;
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 );
List<Integer> topotable = topo(adj, n);
System.out.println(who_wins(topotable, 3 , 5 ));
System.out.println(who_wins(topotable, 1 , 2 ));
}
}
|
Python3
def add(adj, u, v):
adj[u].append(v)
def topo(adj, n):
indeg = [ 0 for i in range (n)]
for i in range (n):
for x in adj[i]:
indeg[x] + = 1
answer = []
visited = [ False for i in range (n)]
q = []
for i in range (n):
if (indeg[i] = = 0 ):
q.append(i)
visited[i] = True
while ( len (q) ! = 0 ):
u = q[ 0 ]
answer.append(u)
q.remove(q[ 0 ])
for x in adj[u]:
indeg[x] - = 1
if (indeg[x] = = 0 and visited[x] = = False ):
q.append(x)
visited[x] = True
return answer
def who_wins(topotable, u, v):
for x in topotable:
if (x = = u):
return u
if (x = = v):
return v
if __name__ = = '__main__' :
adj = [[] for i in range ( 10 )]
n = 7
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 )
topotable = topo(adj, n)
print (who_wins(topotable, 3 , 5 ))
print (who_wins(topotable, 1 , 2 ))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static void add(List< int >[] adj, int u, int v)
{
adj[u].Add(v);
}
static List< int > topo(List< int >[] adj, int n)
{
int [] indeg = new int [n];
for ( int i = 0; i < n; i++) {
foreach ( int x in adj[i]) indeg[x]++;
}
List< int > answer = new List< int >();
bool [] visited = new bool [n];
Queue< int > q = new Queue< int >();
for ( int i = 0; i < n; i++) {
if (indeg[i] == 0) {
q.Enqueue(i);
visited[i] = true ;
}
}
while (q.Count() != 0) {
int u = q.Peek();
answer.Add(u);
q.Dequeue();
foreach ( int x in adj[u])
{
indeg[x]--;
if (indeg[x] == 0 && !visited[x]) {
q.Enqueue(x);
visited[x] = true ;
}
}
}
return answer;
}
static int who_wins(List< int > topotable, int u, int v)
{
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 >();
}
int n = 7;
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);
List< int > topotable = topo(adj, n);
Console.WriteLine(who_wins(topotable, 3, 5));
Console.WriteLine(who_wins(topotable, 1, 2));
}
}
|
Javascript
<script>
brbr
function add(adj, u, v){
adj[u].push(v)
}
function topo(adj, n){
let indeg = new Array(n).fill(0)
for (let i=0;i<n;i++){
for (let x of adj[i]){
indeg[x] += 1
}
}
let answer = []
let visited = new Array(n).fill( false )
let q = []
for (let i=0;i<n;i++){
if (indeg[i] == 0){
q.push(i)
visited[i] = true
}
}
while (q.length != 0){
let u = q.shift()
answer.push(u)
for (let x of adj[u]){
indeg[x] -= 1
if (indeg[x] == 0 && visited[x] == false ){
q.push(x)
visited[x] = true
}
}
}
return answer
}
function who_wins(topotable, u, v){
for (let x of topotable){
if (x == u)
return u
if (x == v)
return v
}
}
let adj = new Array(10).fill(0).map(()=> new Array())
let n = 7
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)
let topotable = topo(adj, n)
document.write(who_wins(topotable, 3, 5), "</br>" )
document.write(who_wins(topotable, 1, 2), "</br>" )
</script>
|
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)
Share your thoughts in the comments
Please Login to comment...