Given a tree with N nodes. Two players A and B start from node 1 and node N respectively. A can visit all the adjacent nodes to the nodes already visited by A but can not visit any nodes which is already visited by B and similarly for B also.
The player who visits more cities win. Find the player who wins if they both play optimally.
Examples:
Input:
Output: A wins
Approach: The optimal solution is that both the Player starts visiting the nodes which lie in the path connecting node 1 and node N. This is because one player cannot visit the nodes already visited by another player so each player will try to limit the number of nodes that can be visited by another player. Then it will be easy to count the number of nodes that can be visited by each player and find out the winner.
The DFS will be used to find out the path between two nodes and mark them one by one like 1 or 2, 1 for A and 2 for B and then mark all the adjacent unvisited nodes with the respective value and then calculate the count of nodes of A and B.
Below is the implementation of the above approach:
// C++ implementation of the above approach #include <bits/stdc++.h> using namespace std;
// Vector to store Tree vector<vector< int > > graph;
// To check if there // is path or not int found = 0, n;
// Path and temporary vector vector< int > path, temp;
// Count of A and B int c_A = 0, c_B = 0;
// Function to find the path connecting 1 to n void find( int i, int prev)
{ // Push the ith node
temp.push_back(i);
// If we reached our destination
if (i == n) {
path = (temp);
return ;
}
for ( int j = 0; j < graph[i].size(); j++)
if (graph[i][j] != prev) {
// Dfs for its children
find(graph[i][j], i);
}
// Remove the node
temp.pop_back();
} // Function to mark all the adjacent // unvisited nodes void mark( int i, int visited[], int c)
{ if (!visited[i]) {
// Increase the count
if (c == 1)
c_A++;
else
c_B++;
}
visited[i] = c;
// Increase the count
if (c == 1)
c_A++;
else
c_B++;
// Dfs for all its unvisited adjacent nodes
for ( int j = 0; j < graph[i].size(); j++)
if (!visited[graph[i][j]])
mark(graph[i][j], visited, c);
} // Function to find the winner among the players void findWinner()
{ // Finds the path
find(1, -1);
int visited[n + 1] = { 0 };
for ( int i = 0; i < path.size(); i++) {
// Mark nodes visited by
// A as 1 and B as 2
if (i < ceil (path.size() / 2.0))
visited[path[i]] = 1, c_A++;
else
visited[path[i]] = 2, c_B++;
}
// Mark all the adjacent unvisited nodes
for ( int i = 0; i < path.size(); i++)
mark(path[i],
visited,
visited[path[i]]);
if (c_A > c_B)
cout << "A wins" ;
else if (c_A < c_B)
cout << "B wins" ;
else
cout << "Draw" ;
} // Driver code int main()
{ n = 7;
graph.clear();
graph.resize(n + 1);
// Graph
graph[6].push_back(4);
graph[4].push_back(6);
graph[6].push_back(5);
graph[5].push_back(6);
graph[5].push_back(7);
graph[7].push_back(5);
graph[5].push_back(2);
graph[2].push_back(5);
graph[3].push_back(4);
graph[4].push_back(3);
graph[1].push_back(4);
graph[4].push_back(1);
findWinner();
return 0;
} |
// Java implementation of the // above approach import java.util.*;
class GFG{
// Vector to store Tree static Vector<Integer> []graph;
// To check if there // is path or not static int found = 0 , n;
// Path and temporary vector static Vector<Integer> path =
new Vector<>();
static Vector<Integer> temp =
new Vector<>();
// Count of A and B static int c_A = 0 , c_B = 0 ;
// Function to find the path // connecting 1 to n static void find( int i,
int prev)
{ // Push the ith node
temp.add(i);
// If we reached our
// destination
if (i == n)
{
path = (temp);
return ;
}
for ( int j = 0 ;
j < graph[i].size(); j++)
if (graph[i].get(j) != prev)
{
// Dfs for its children
find(graph[i].get(j), i);
}
// Remove the node
temp.remove(temp.size() - 1 );
} // Function to mark all the // adjacent unvisited nodes static void mark( int i,
int visited[],
int c)
{ if (visited[i] > 0 )
{
// Increase the count
if (c == 1 )
c_A++;
else
c_B++;
}
visited[i] = c;
// Increase the count
if (c == 1 )
c_A++;
else
c_B++;
// Dfs for all its unvisited
// adjacent nodes
for ( int j = 0 ;
j < graph[i].size(); j++)
if (visited[graph[i].get(j)] > 0 )
mark(graph[i].get(j),
visited, c);
} // Function to find the winner // among the players static void findWinner()
{ // Finds the path
find( 1 , - 1 );
int visited[] = new int [n + 1 ];
for ( int i = 0 ;
i < path.size(); i++)
{
// Mark nodes visited by
// A as 1 and B as 2
if (i < Math.ceil(path.size() / 2.0 ))
{
visited[path.get(i)] = 1 ;
c_A++;
}
else
{
visited[path.get(i)] = 2 ;
c_B++;
}
}
// Mark all the adjacent
// unvisited nodes
for ( int i = 0 ;
i < path.size(); i++)
mark(path.get(i),
visited,
visited[path.get(i)]);
if (c_A > c_B)
System.out.print( "A wins" );
else if (c_A < c_B)
System.out.print( "B wins" );
else
System.out.print( "Draw" );
} // Driver code @SuppressWarnings ( "unchecked" )
public static void main(String[] args)
{ n = 7 ;
graph = new Vector[n + 1 ];
for ( int i = 0 ;
i < graph.length; i++)
graph[i] = new Vector<Integer>();
// Graph
graph[ 6 ].add( 4 );
graph[ 4 ].add( 6 );
graph[ 6 ].add( 5 );
graph[ 5 ].add( 6 );
graph[ 5 ].add( 7 );
graph[ 7 ].add( 5 );
graph[ 5 ].add( 2 );
graph[ 2 ].add( 5 );
graph[ 3 ].add( 4 );
graph[ 4 ].add( 3 );
graph[ 1 ].add( 4 );
graph[ 4 ].add( 1 );
findWinner();
} } // This code is contributed by Amit Katiyar |
# Python3 implementation of the above approach from math import ceil, floor
# Vector to store Tree graph = [[] for i in range ( 1000 )]
# To check if there # is path or not found = 0
n = 0
# Path and temporary vector path = []
temp = []
# Count of A and B c_A = 0
c_B = 0
# Function to find the path connecting 1 to n def find(i, prev):
global c_A, c_B, path
# Push the ith node
temp.append(i)
# If we reached our destination
if (i = = n):
path = temp
return
for j in graph[i]:
if j ! = prev:
# Dfs for its children
find(j, i)
# Remove the node
del temp[ - 1 ]
# Function to mark all the adjacent # unvisited nodes def mark(i, visited, c):
global c_B, c_A
if visited[i] = = 0 :
# Increase the count
if (c = = 1 ):
c_A + = 1
else :
c_B + = 1
visited[i] = c
# Increase the count
if (c = = 1 ):
c_A + = 1
else :
c_B + = 1
# Dfs for all its unvisited adjacent nodes
for j in graph[i]:
if (visited[j] = = 0 ):
mark(j, visited, c)
# Function to find the winner among the players def findWinner():
global c_B, c_A, path
# Finds the path
find( 1 , - 1 )
visited = [ 0 for i in range (n + 1 )]
for i in range ( len (path)):
# Mark nodes visited by
# A as 1 and B as 2
if (i < ceil( len (path) / 2.0 )):
visited[path[i]] = 1
c_A + = 1
else :
visited[path[i]] = 2
c_B + = 1
# Mark all the adjacent unvisited nodes
for i in path:
mark(i, visited, visited[i])
if (c_A > c_B):
print ( "A wins" )
elif (c_A < c_B):
print ( "B wins" )
else :
print ( "Draw" )
# Driver code n = 7
# Graph graph[ 6 ].append( 4 )
graph[ 4 ].append( 6 )
graph[ 6 ].append( 5 )
graph[ 5 ].append( 6 )
graph[ 5 ].append( 7 )
graph[ 7 ].append( 5 )
graph[ 5 ].append( 2 )
graph[ 2 ].append( 5 )
graph[ 3 ].append( 4 )
graph[ 4 ].append( 3 )
graph[ 1 ].append( 4 )
graph[ 4 ].append( 1 )
findWinner() # This code is contributed by Mohit Kumar |
// C# implementation of the // above approach using System;
using System.Collections.Generic;
class GFG{
// List to store Tree static List< int > []graph;
// To check if there // is path or not static int found = 0, n;
// Path and temporary vector static List< int > path =
new List< int >();
static List< int > temp =
new List< int >();
// Count of A and B static int c_A = 0, c_B = 0;
// Function to find the path // connecting 1 to n static void find( int i,
int prev)
{ // Push the ith node
temp.Add(i);
// If we reached our
// destination
if (i == n)
{
path = (temp);
return ;
}
for ( int j = 0;
j < graph[i].Count; j++)
if (graph[i][j] != prev)
{
// Dfs for its children
find(graph[i][j], i);
}
// Remove the node
temp.Remove(temp.Count - 1);
} // Function to mark all the // adjacent unvisited nodes static void mark( int i,
int []visited,
int c)
{ if (visited[i] > 0)
{
// Increase the count
if (c == 1)
c_A++;
else
c_B++;
}
visited[i] = c;
// Increase the count
if (c == 1)
c_A++;
else
c_B++;
// Dfs for all its unvisited
// adjacent nodes
for ( int j = 0;
j < graph[i].Count; j++)
if (visited[graph[i][j]] > 0)
mark(graph[i][j],
visited, c);
} // Function to find the winner // among the players static void findWinner()
{ // Finds the path
find(1, -1);
int []visited = new int [n + 1];
for ( int i = 0;
i < path.Count; i++)
{
// Mark nodes visited by
// A as 1 and B as 2
if (i < Math.Ceiling(path.Count / 2.0))
{
visited[path[i]] = 1;
c_A++;
}
else
{
visited[path[i]] = 2;
c_B++;
}
}
// Mark all the adjacent
// unvisited nodes
for ( int i = 0;
i < path.Count; i++)
mark(path[i],
visited,
visited[path[i]]);
if (c_A > c_B)
Console.Write( "A wins" );
else if (c_A < c_B)
Console.Write( "B wins" );
else
Console.Write( "Draw" );
} // Driver code public static void Main(String[] args)
{ n = 7;
graph = new List< int >[n + 1];
for ( int i = 0;
i < graph.Length; i++)
graph[i] = new List< int >();
// Graph
graph[6].Add(4);
graph[4].Add(6);
graph[6].Add(5);
graph[5].Add(6);
graph[5].Add(7);
graph[7].Add(5);
graph[5].Add(2);
graph[2].Add(5);
graph[3].Add(4);
graph[4].Add(3);
graph[1].Add(4);
graph[4].Add(1);
findWinner();
} } // This code is contributed by shikhasingrajput |
<script> // Javascript implementation of the // above approach // Vector to store Tree let graph; // To check if there // is path or not let found = 0, n; // Path and temporary vector let path = []; let temp = []; // Count of A and B let c_A = 0, c_B = 0; // Function to find the path // connecting 1 to n function find(i, prev)
{ // Push the ith node
temp.push(i);
// If we reached our
// destination
if (i == n)
{
path = (temp);
return ;
}
for (let j = 0;
j < graph[i].length; j++)
{
if (graph[i][j] != prev)
{
// Dfs for its children
find(graph[i][j], i);
}
}
// Remove the node
temp.pop();
} // Function to mark all the // adjacent unvisited nodes function mark(i, visited, c)
{ if (visited[i] > 0)
{
// Increase the count
if (c == 1)
c_A++;
else
c_B++;
}
visited[i] = c;
// Increase the count
if (c == 1)
c_A++;
else
c_B++;
// Dfs for all its unvisited
// adjacent nodes
for (let j = 0;
j < graph[i].length; j++)
if (visited[graph[i][j]] > 0)
mark(graph[i][j], visited, c);
} // Function to find the winner // among the players function findWinner()
{ // Finds the path
find(1, -1);
let visited = new Array(n + 1);
for (let i = 0;
i < path.length; i++)
{
// Mark nodes visited by
// A as 1 and B as 2
if (i < Math.ceil(path.length / 2.0))
{
visited[path[i]] = 1;
c_A++;
}
else
{
visited[path[i]] = 2;
c_B++;
}
}
// Mark all the adjacent
// unvisited nodes
for (let i = 0;
i < path.length; i++)
mark(path[i], visited,
visited[path[i]]);
if (c_A > c_B)
document.write( "A wins" );
else if (c_A < c_B)
document.write( "B wins" );
else
document.write( "Draw" );
} // Driver code n = 7; graph = new Array(n + 1);
for (let i = 0;
i < graph.length; i++)
graph[i] = [];
// Graph graph[6].push(4); graph[4].push(6); graph[6].push(5); graph[5].push(6); graph[5].push(7); graph[7].push(5); graph[5].push(2); graph[2].push(5); graph[3].push(4); graph[4].push(3); graph[1].push(4); graph[4].push(1); findWinner(); // This code is contributed by patel2127 </script> |
A wins