// L-38 MCS 360 Mon 27 Nov 2017 : adjacency_list.cpp

/* The adjacency list representation of a graph is a vector of lists.
   The i-th list stores the vertices connected to the i-th vertex.
   A graph can be directed or undirected, weighted or not.  */

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <vector>
#include <list>

using namespace std;

void allocate_adjacency_list ( vector< list<size_t> >& lst, size_t dim );
// Allocates space for an adjacency list of dimension dim.

void random_directed_graph ( vector< list<size_t> >& lst );
// Fills up the adjacency list for a random directed graph.

void write_adjacency_list ( vector< list<size_t> >& lst );
// Writes the adjacency list to screen.

int main ( void )
{
   cout << "Give the number of vertices : ";
   size_t n; cin >> n;

   vector< list<size_t> > lst;

   allocate_adjacency_list(lst, n);

   random_directed_graph(lst);

   write_adjacency_list(lst);

   return 0;
}

void allocate_adjacency_list
 ( vector< list<size_t> >& lst, size_t dim )
{
   for(size_t i=0; i<dim; i++)
   {
      list<size_t> row;
      lst.push_back(row);
   }
}

void random_directed_graph
 ( vector< list<size_t> >& lst )
{
   const size_t dim = lst.size();

   for(size_t i=0; i<dim; i++)
   {
      for(size_t j=0; j<dim; j++) 
      {
         size_t rnd = rand() % 2;
         if(rnd != 0) lst[i].push_back(j);
      }
   }
}

void write_adjacency_list ( vector< list<size_t> >& lst )
{
   const size_t dim = lst.size();

   for(size_t i=0; i<dim; i++)
   {
      cout << i;

      for(list<size_t>::const_iterator it=lst[i].begin();
          it != lst[i].end(); it++)
         cout << " -> " << *it;

      cout << endl;
   }  
}
