main.cc.html
//**************************************************************************
//
//      CSE 465 Programming Assignment #3
//      By Anirudh Modi (avm105@psu.edu) on 4/14/98-Tue
//
//**************************************************************************
//	Running time of algorithm -> O[(E+V)log V]
//**************************************************************************
// 	Have implemented the following extra options ->
//		1. Hashing procedure for Vertex Names (hash.cc)
//		2. Decrease_Key operation takes O(log N) time (priqueue.cc)
//		3. There is no memory leak
//**************************************************************************
//	Also implemented :
//		1. General code so that any "source" can be specified
//		2. Prints the Heap status at every stage if desired
//		3. Undirectional graphs can also be read
//**************************************************************************
#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include "vertex.h"
#include "adjlist.h"
#include "hash.h"
#include "dijkstra.h"
//**************************************************************************
#define SIZE 25000		// Max size of Hash Table and Adj List
#define BUF_SIZE 1000		// Max Size for Reading every line of Input
//**************************************************************************
#define PRINT_DIJKSTRA 1	// Flag to print the list of shortest edges
#define PRINT_VERTEX_LIST 0	// Flag to print the vertex list at start
#define PRINT_HEAP_STATUS 0	// Flag to print heap after each step
#define ASK_FOR_SOURCE 0	// Flag to ask for source vertex (else 
				// defaults to first vertex read)
#define IS_UNDIRECTIONAL 0	// Flag for undirectional graph
//**************************************************************************
void Read_Graph (char *filename,AdjList& G,HashTable& T,int is_undirectional);
int  Get_Source(HashTable& T);
void Read_Dest (int source, Vertex *V, AdjList& G, HashTable& T);
//**************************************************************************
int main (int argc, char *argv[])
{
if (argc != 2) 
	{
	 cerr << "Syntax: " << argv[0] << " <graph-file>" << endl;
	 exit(-1);
	}

HashTable T(SIZE);	// Hash Table for Vertices
AdjList   G(SIZE);	// Graph as an Adjency List representation

if (IS_UNDIRECTIONAL) 
	 cout << "Reading UNDIRECTIONAL Graph..." << endl;
else
	 cout << "Reading DIRECTIONAL Graph (digraph)..." << endl;

Read_Graph(argv[1],G,T,IS_UNDIRECTIONAL);		// Read the Graph
int vert = G.no_of_verts();
int edges = G.no_of_edges();
if (IS_UNDIRECTIONAL) edges /= 2;

if (vert == 0 || edges == 0)
	{
	 cerr << "No vertices and/or edges specified..." << endl;
	 cerr << "Invalid input file !!" << endl;
	 cerr << "Exiting....." << endl;
	 exit(-1);
	}

cout << "Number of vertices = " << vert << endl;
cout << "Number of edges = " << edges << endl << endl;

int source;

if (ASK_FOR_SOURCE)
	source = Get_Source(T);
else
	source = 1;

Vertex *V = new Vertex[vert];	// List of edges forming shortest paths

dijkstra(source,G,V,T,PRINT_HEAP_STATUS); // Call Dijkstra's routine

if (PRINT_VERTEX_LIST)
	{
	 cout << '\t' << "Vertex list" << endl;
	 cout << '\t' << "-----------" << endl;
	 for (int i=1;i<=vert;i++) 
	 	cout << '\t' << i << '\t' << T.name_of(i) << endl;
	 cout << endl;
	 cout << '\t' << "Source: " << T.name_of(source) << endl << endl;
	}

if (PRINT_DIJKSTRA)
	Print_Dijkstra(source,V,T);

Read_Dest(source,V,G,T);

delete [] V;

cout << endl << endl;
cout << "EOF character pressed ! Exiting.............." << endl;
}
//**************************************************************************
void Read_Graph (char *filename,AdjList& G,HashTable& T,int is_undirectional)
{
ifstream inp(filename);
char buf[BUF_SIZE];

if (!inp)
	{
	 cerr << "Invalid filename \"" << filename << "\" !!" << endl;
	 cerr << "Exiting........." << endl;
	 exit(-1);
	}

while (inp.getline(buf,BUF_SIZE) && inp.good() && !inp.eof())
	{
	 char *vertname2 = strpbrk(buf, " \t");
	 *vertname2++ = '\0';
	 char *buf2 = strpbrk(vertname2, " \t");
	 *buf2++ = '\0';
	 int weight = atoi(buf2);
	 int ptA = T.id_of(buf);
	 int ptB = T.id_of(vertname2);
	 G.add_Edge(ptA,ptB,weight);
	 if (is_undirectional)
	 	G.add_Edge(ptB,ptA,weight);
	}
G.setVerts(T.nodes_of());

return;
}
//**************************************************************************
int Get_Source(HashTable& T)
{
int source;
char buf[BUF_SIZE];

cout << "Source: ";
while (cin.getline(buf,BUF_SIZE) && cin.good() && !cin.eof())
	{
	 source = T.find(buf);
	 if (source) break;
	 cout 	<< endl << '\t' << "Unkown vertex \"" << buf 
		 	<< "\" !! Try again !" << endl << endl;
	 cout << "Source: ";
	}
cout << endl;
return source;
}
//**************************************************************************
void Read_Dest (int source, Vertex *V, AdjList& G, HashTable& T)
{
char buf[BUF_SIZE];

cout << "Destination: ";
while (cin.getline(buf,BUF_SIZE) && cin.good() && !cin.eof())
	{
	 int dest = T.find(buf);
	 if (dest)
	 	 Print_Path(source,dest,V,G,T);
	 else if (strlen(buf))
		 cout 	<< endl << '\t' << "Unkown vertex \"" << buf 
		 	<< "\" !! Try again !" << endl << endl;
	 cout << "Destination: ";
	}
}
//**************************************************************************