C++ program to find winner of cell coloring game

Suppose we have two arrays A and B both are with N elements each. Consider Amal and Bimal are playing a game on a board whose cell numbers are numbered from 1 to N. And N-1 roads. Roads are connecting two cells. So ith road is connecting A[i] to B[i]. Every cell can be reached from every other cell by repeatedly traveling to an adjacent cell. Initially the cell 1 is marked as black color, and cell N is white. Other cells are not colored. Amal plays first, and they are playing alternatively. Amal selects an uncolored cells that is adjacent to black cell and paints black. Bimal selects an uncolored cell that is adjacent to a white cell and paints white. When a player cannot paint a cell, he looses. We have to find the winner.

So, if the input is like A = [3, 1, 3, 7, 5, 1]; B = [6, 2, 1, 4, 7, 4], then the output will be Amal, because if Amal first paints cell 2 black, he will win regardless of Bimal's moves.

Steps

To solve this, we will follow these steps −

N := 99999
Define three large arrays p, d, and ssz
Define a function dfs(), this will take nd, par, dep,
p[nd] := par
d[nd] := dep
ssz[nd] := 1
for each node i in adjList[nd], do
if i XOR par is non-zero, then:
dfs(i, nd, dep + 1)
ssz[nd] := ssz[nd] + ssz[i]
From the main method, do the following:
n := size of A
for initialize i := 1, when i < n, update (increase i by 1), do:
u := A[i - 1], v := B[i - 1]
insert v at the end of adjList[u]
insert u at the end of adjList[v]
dfs(1, 1, 0)
nd := n
for initialize i := 0, when i < (d[n] - 1) / 2, update (increase i by 1), do:
nd := p[nd]
return if 2 * ssz[nd] >= n, then "Bimal", otherwise "Amal"

Example

Let us see the following implementation to get better understanding −

#include <bits/stdc++.h>
using namespace std;

int N = 99999;

vector<int> p(N), d(N), ssz(N);

void dfs(int nd, int par, int dep){
p[nd] = par;
d[nd] = dep;
ssz[nd] = 1;
if (i ^ par){
dfs(i, nd, dep + 1);
ssz[nd] += ssz[i];
}
}
}
string solve(vector<int> A, vector<int> B){
int n = A.size();
for (int i = 1; i < n; i++){
int u = A[i - 1], v = B[i - 1];
}
dfs(1, 1, 0);
int nd = n;
for (int i = 0; i < (d[n] - 1) / 2; i++)
nd = p[nd];
return (2 * ssz[nd] >= n ? "Bimal" : "Amal");
}
int main(){
vector<int> A = { 3, 1, 3, 7, 5, 1 };
vector<int> B = { 6, 2, 1, 4, 7, 4 };
cout << solve(A, B) << endl;
}

Input

{ 3, 1, 3, 7, 5, 1 }, { 6, 2, 1, 4, 7, 4 }

Output

Amal