// Dalton Green, Evan Crook
// Winter 2015, CS140

/* 
 * Neighbors contains every node's neighbors in node order
 * E.G. neighbors of 0, neighbors of 1, ..., neighbors of n
 *
 * neighborsIndex stores the start of each node's neighbors in the
 * neighbor array. Thus neighbors[ neighborsIndex[5] ] will return the
 * first neighbor of node 5. 
 * 
 * values is the array of the value at each node
 * 
 * n is the number of nodes in the graph
 */

#include "includes.h"

// Straight sequential implementation of BFS for reference.
int64_t* SBFS(int64_t neighbors[], int64_t neighborsIndex[], int64_t depth[], int64_t root, int64_t n, int64_t edgeCount) {
  
  // Parent array for building the tree
  // Root has no parent
  int64_t* parent = new int64_t[n+1];
  parent[root] = -1;
  int64_t d = 0;
  depth[root] = d;
  
  // Visited array to determine what has or has not been touched
  // All values are initialized to 0
  int64_t* visited = new int64_t[n+1];
  for(int64_t i = 0; i <= n; i++) { visited[i] = 0; }
  
  // List that will store nodes to visit
  // Initially contains only the root
  std::deque<int64_t> frontier;
  frontier.push_back(root);
  visited[root] = 1;
  
  int64_t totalvisited = 0;
  while (!frontier.empty() ) {
    int64_t currNode = frontier.front();
    frontier.pop_front();
    totalvisited++;
    //std::cout << "Visiting " << currNode << std::endl;
    int64_t iter, adjNode;
    int64_t ub = (neighborsIndex[currNode+1] > edgeCount) ? edgeCount : neighborsIndex[currNode+1];
    for(iter = neighborsIndex[currNode]; iter < ub; iter++) {
        adjNode = neighbors[iter];
        if(!visited[adjNode]) {
          frontier.push_back(adjNode);
          visited[adjNode] = 1;
          depth[adjNode] = depth[currNode]+1; 
        }
      }
  }

  return parent;
}