I need help with this function: int maxChainLength (Graph graph, int iVertex); T
ID: 3818420 • Letter: I
Question
I need help with this function:
int maxChainLength(Graph graph, int iVertex);
The function has to returns the count of the number of vertices in the longest chain that begins with the specified vertex. The function also has to be recursive.
For example, if it starts at CS1083 and goes through the graph and should return 4 because the longest chain is CS1083 through CS373 or cs3733 or cs3433.
This is all I have right now:
int findCourse(Graph graph, char szCourseId[])
{
//int to be used in the for loop
int i;
//goes through the specified array to find the course id
for(i = 0; i < graph->iNumVertices; i++)
{
//if its found it returns i
if(strcmp(graph->vertexM[i].szCourseId, szCourseId)== 0)
return i;
}
return -1;
}
// int ivertex = findCourse(Graph graph, courseID[ ])
int maxChain(Graph graph, int iVertex){ // <--------- FUNCTION IM HAVING PROBLEM WITH
EdgeNode *e;
int iCount;
for(e = graph->vertexM[iVertex].successorList; e != NULL; e = e->pNextEdge){ // The for loop goes through the entire graph.
maxChain(graph, e->iSuccVertex);
}
return iCount;
}
header file:
// EdgeNode represents one edge in a graph
typedef struct EdgeNode
{
int iPrereqVertex; // prereq
int iSuccVertex; // successor
struct EdgeNode *pNextEdge; // points to next edge
} EdgeNode;
typedef struct Vertex
{
char szCourseId[8]; // Course Identifier
char szCourseName[21]; // Course Full Name
char szDept[4]; // Department (e.g., CS, MAT)
int bExists; // pgm6 DELETE command causes this to be set to TRUE
// TRUE - this vertex exists, FALSE - deleted
EdgeNode * prereqList; // badically means it is going to go backwards when pNextEdge
EdgeNode * successorList; //means it is going forward when pNextEdge
int iSemesterLevel;
int iHashChainNext; // pgm 6 extra credit
int iDistSource;
} Vertex;
// GraphImp of a double adjacency list graph
typedef struct
{
int iNumVertices;
Vertex vertexM[MAX_VERTICES];
} GraphImp;
typedef GraphImp *Graph;
) | > math1224Explanation / Answer
//main.c
#define CRT SECURE NO WARNINGS 1
//include files
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include "cs2123p5.h"
int main(int argc, char *argv[])
{
int iScanfCnt = 0;
char szName[50];
char szCourse[50];
char szCommand[50];
char szInputBuffer[100];
char szPrereq[50];
char szDummy[50];//this takes course and will exist for each sscanf
char szPrintname[50];
int bCycle;
int iVertexCnt = 0; //this is incremented after each iteration to store the array subscript
Graph graph = newGraph();
while(fgets(szInputBuffer, 100, stdin) != NULL)
{
//the first argument here doesn't work so i dont know
//how to use getToken and sscanf at the same time
getToken(szInputBuffer, szCommand, 50);
//this if saves the current course in case a prereq
//comes after it in the input so it can search for it
//and add it to the graph with the right prereqs and successors
if(strcmp(szCommand, "COURSE") == 0)
{
iScanfCnt = sscanf(szInputBuffer, "%s %s %[^ ]"
, szDummy
, graph->vertexM[iVertexCnt].szCourseId
, graph->vertexM[iVertexCnt].szCourseName);
if(iScanfCnt < 3)
printf("Course input invalid ");
strcpy(szName, graph->vertexM[iVertexCnt].szCourseId);
strcpy(szCourse, graph->vertexM[iVertexCnt].szCourseName);
if(findCourse(graph, graph->vertexM[iVertexCnt].szCourseId) < 0)// if the course already exists it doesn't create an entire new one
{
insertCourse(graph, iVertexCnt);
iVertexCnt++;
graph->iNumVertices++;
}
printf("%s %s %s "
, szCommand
, szName
, szCourse);
//we'll add in the exception that the prereq inserted a course to overwrite the tbd later
}
//prereq should already exist otherwise this will cause an error
else if(strcmp(szCommand, "PREREQ") == 0)
{
iScanfCnt = sscanf(szInputBuffer, "%s %s"
, szDummy
, szPrereq);
if(iScanfCnt < 2)
printf("Prereq input invalid ");
//local variable iPV to hold findCourse info
int iPV = findCourse(graph, szPrereq);
// if PreReqCourse is not in the vertex, then insert it with TBD szCourseName and its id
if (iPV == -1) //findcourse returns -1 if course not found because NULL won't work unless we figure that out
{
// create Vertex for new PreReqCourse which wasnt in the Graph before
strcpy(graph->vertexM[iVertexCnt].szCourseId, szPrereq);
strcpy(graph->vertexM[iVertexCnt].szCourseName, "TBD");
// allocate edgeNodes for new course
insertCourse(graph, iVertexCnt);
iVertexCnt++;
graph->iNumVertices++;
}
//takes prereq and course subscripts and inserts them
bCycle = causesCycle(graph, iPV, findCourse(graph, szName));
if (bCycle == TRUE)
printf("Prereq insertion causes cycle ");
else
insertPrereq(graph, iPV, findCourse(graph, szName));
printf("%s %s "
, szCommand
, szPrereq);
}
else if(strcmp(szCommand, "PRTONE") == 0)
{
iScanfCnt = sscanf(szInputBuffer, "%s %s"
, szDummy
, szPrintname);
if(iScanfCnt < 2)
printf("Printone input invalid ");
//calls printone function
printf("%s %s "
, szCommand
, szPrintname);
printOne(graph, findCourse(graph, szPrintname));
}
//just calls print function, no scanf required
else if(strcmp(szCommand, "PRTALL") == 0)
{
printf("%s ", szCommand);
printAllInList(graph);
}
else if(strcmp(szCommand, "PRTSUCC") == 0)
{
iScanfCnt = sscanf(szInputBuffer, "%s %s"
, szDummy
, szPrintname);
if(iScanfCnt < 2)
printf("Print successor input invalid ");
//calls print successor
//pretty sure this is for successor
printf("%s %s "
, szCommand
, szPrintname);
printf("%-6s %-20s "
,graph->vertexM[findCourse(graph, szPrintname)].szCourseId
,graph->vertexM[findCourse(graph, szPrintname)].szCourseName);
printTraversal(graph, findCourse(graph, szPrintname), 1);
}
else if(strcmp(szCommand, "MAXCHAIN") == 0)
{
iScanfCnt = sscanf(szInputBuffer, "%s %s"
, szDummy
, szPrintname);
if(iScanfCnt < 2)
printf("Max Chain input invalid ");
//calls max chain
printf("%s %s Max Chain for %s is %d "
, szCommand
, szPrintname
, graph->vertexM[findCourse(graph, szPrintname)].szCourseId
, maxChain(graph, findCourse(graph, szPrintname)));
}
else if(strcmp(szCommand, "PRTLONGS") == 0)
{
iScanfCnt = sscanf(szInputBuffer, "%s %s"
, szDummy
, szPrintname);
if(iScanfCnt < 2)
printf("Print long input invalid");
//calls print longs
int pathM[MAX_VERTICES];
printLongChains(graph, findCourse(graph, szPrintname), pathM
, 0, maxChain(graph, findCourse(graph, szPrintname)));
printf("%s %s "
, szCommand
, szPrintname);
}
//just calls print function, no scanf required
else if(strcmp(szCommand, "PRTSINKS") == 0)
{
printf("%s", szCommand);
printSinks(graph);
}
//just calls print function, no scanf required
else if(strcmp(szCommand, "PRTSOURCES") == 0)
{
printf("%s", szCommand);
printSources( graph);
}
else if(strcmp(szCommand, "*"))
{
char szComments[50];
iScanfCnt = sscanf(szInputBuffer, "%[^ ]", szComments);
printf("%s", szComments);
}
}
}
/************************************************/
int findCourse(Graph graph, char szCourseId[])
{
int i;
for (i = 0; i < graph->iNumVertices; i++)
{
if (strcmp(szCourseId, graph->vertexM[i].szCourseId) == 0)
{
return i;
}
}
/*we want this to be NULL not 0 if 0 that means it would be the vertexM[0] we want to use a
conditional for if (!= NULL) or if (== NULL)*/
return -1;
}
/*************************************************/
char * getToken(char *pszInputTxt, char szToken[], int iTokenSize)
{
int iDelimPos; // found position of delim
int iCopy; // number of characters to copy
char szDelims[20] = " "; // delimiters
szToken[0] = '';
// check for NULL pointer
if (pszInputTxt == NULL)
ErrExit(ERR_ALGORITHM
, "getToken passed a NULL pointer");
// Check for no token if at zero byte
if (*pszInputTxt == '')
return NULL;
// get the position of the first delim
iDelimPos = strcspn(pszInputTxt, szDelims);
// if the delim position is at the first character, return no token.
if (iDelimPos == 0)
return NULL;
// see if we have more characters than target token, if so, trunc
if (iDelimPos > iTokenSize)
iCopy = iTokenSize; // truncated size
else
iCopy = iDelimPos;
// copy the token into the target token variable
memcpy(szToken, pszInputTxt, iCopy);
szToken[iCopy] = ''; // null terminate
// advance the position
pszInputTxt += iDelimPos;
if (*pszInputTxt == '')
return pszInputTxt;
else
return pszInputTxt + 1;
}
/**********************************/
void insertCourse(Graph graph, int iVertex)
{
graph->vertexM[iVertex].prereqList = NULL;
graph->vertexM[iVertex].successorList = NULL;
}
/***************************************/
void ErrExit(int iexitRC, char szFmt[], ... )
{
va_list args; // This is the standard C variable argument list type
va_start(args, szFmt); // This tells the compiler where the variable arguments
// begins. They begin after szFmt.
printf("ERROR: ");
vprintf(szFmt, args); // vprintf receives a printf format string and a
// va_list argument
va_end(args); // let the C environment know we are finished with the
// va_list argument
printf(" Encountered in file %s ", __FILE__); // this 2nd arg is filled in by
// the pre-compiler
exit(iexitRC);
}
void exitUsage(int iArg, char *pszMessage, char *pszDiagnosticInfo)
{
switch (iArg)
{
case USAGE_ERR:
fprintf(stderr, "Error: %s %s "
, pszMessage
, pszDiagnosticInfo);
break;
case USAGE_ONLY:
break;
default:
fprintf(stderr, "Error: bad argument #%d. %s %s "
, iArg
, pszMessage
, pszDiagnosticInfo);
}
// print the usage information for any type of command line error
fprintf(stderr, "p2 -c courseFileName -q queryFileName ");
if (iArg == USAGE_ONLY)
exit(USAGE_ONLY);
else
exit(ERR_COMMAND_LINE);
}
=======================================================================
//cs2123p5.h
#define MAX_TOKEN 50 // Maximum number of actual characters for a token
#define MAX_LINE_SIZE 100 // Maximum number of character per input line
#define MAX_VERTICES 70
// Error constants (program exit values)
#define ERR_COMMAND_LINE 900 // invalid command line argument
#define ERR_ALGORITHM 903 // Unexpected error in algorithm
#define ERR_TOO_MANY_COURSE 1 // Too many courses
#define ERR_BAD_COURSE 3 // Bad Course Data
#define ERR_BAD_PREREQ 4 // Bad Prereq Data
#define ERR_MISSING_SWITCH "missing switch"
#define ERR_EXPECTED_SWITCH "expected switch, found"
#define ERR_MISSING_ARGUMENT "missing argument for"
// exitUsage control
#define USAGE_ONLY 0 // user only requested usage information
#define USAGE_ERR -1 // usage error, show message and usage information
// boolean constants
#define FALSE 0
#define TRUE 1
// EdgeNode represents one edge in a graph
typedef struct EdgeNode
{
int iPrereqVertex; // prereq
int iSuccVertex; // successor
struct EdgeNode *pNextEdge; // points to next edge
} EdgeNode;
typedef struct Vertex
{
char szCourseId[8]; // Course Identifier
char szCourseName[21]; // Course Full Name
char szDept[4]; // Department (e.g., CS, MAT)
int bExists; // pgm6 DELETE command causes this to be set to TRUE
// TRUE - this vertex exists, FALSE - deleted
EdgeNode * prereqList;
EdgeNode * successorList;
int iSemesterLevel;
int iHashChainNext; // pgm 6 extra credit
int iDistSource;
} Vertex;
// GraphImp of a double adjacency list graph
typedef struct
{
int iNumVertices;
Vertex vertexM[MAX_VERTICES];
} GraphImp;
typedef GraphImp *Graph;
// Degree Plan
typedef struct
{
int semesterM[5][MAX_VERTICES];
int bIncludeM[MAX_VERTICES];
} PlanImp;
typedef PlanImp * Plan;
typedef struct
{
int iPrimayMax ; // Max subscript in the primary portion
// Any subscript higher is in overflow
} HashTable;
// Prototypes
// Recursive functions for program 5
int maxChain(Graph graph, int iVertex);
void printTraversal(Graph graph, int iCourseVertex, int indent);
void printLongChains(Graph graph, int iVertex, int pathM[], int iLevel, int iLongLength);
int causesCycle(Graph graph, int iPrereqVertex, int iVertex);
// Non-recursive for program 5
int findCourse(Graph graph, char szCourseId[]);
void insertPrereq(Graph graph, int iPrereqVertex, int iCourseVertex);
void printAllInList(Graph graph);
void printOne(Graph graph, int iVertex);
void printSources(Graph graph);
void printSinks(Graph graph);
void insertCourse(Graph graph, int iVertex);
EdgeNode * allocateEdgeNode();
Graph newGraph();
// Program 6 function for delete
void deleteCourse (Graph graph, int iVertex);
// Program 6 functions for Plan
void doPlan(Graph graph, Plan plan);
void setLevel(Graph g, Plan plan, int iVertex, int iLev);
Plan newPlan();
// functions in most programs, but require modifications
void processCommandSwitches(int argc, char *argv[], char **ppszCommandFileName);
void exitUsage(int iArg, char *pszMessage, char *pszDiagnosticInfo);
// Utility routines provided by Larry
void ErrExit(int iexitRC, char szFmt[], ...);
char * getToken(char *pszInputTxt, char szToken[], int iTokenSize);
/*
WARNING macro
Parameters:
I szFmt - a printf format
I ... - a variable number of parameters corresponding to szFmt's
format codes.
Results:
Prints "WARNING" and the value(s) specified by the szFmt.
Notes:
Since this generates multiple C statements, we surround them
with a dummy do while(0) which only executes once. Notice that the
dummy do while isn't ended with a ";" since the user of
the macro naturally specifies a ";". Example:
if (x != 0)
WARNING("X must be blah blah");
else
{ // normal processing
....
}
If we used {} in the macro definition instead of the dummy do while(0),
the generated code would have a bad ";":
if (x != 0)
{
printf(" WARNING: ");
printf("X must be blah blah");
printf(" ");
} ; // yuck, bad ";" causing the compiler to not understand the else
else
{ // normal processing
....
}
*/
#define WARNING(szFmt, ...) do {
printf(" WARNING: ");
printf(szFmt, __VA_ARGS__);
printf(" ");
} while (0)
===========================================================================
#define CRT SECURE NO WARNINGS 1
//include files
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include "cs2123p5.h"
void printAllInList(Graph graph)
{
EdgeNode *e; //pointer variable used for traversing adjacency list
int iCount = 0; //local variable used for printing ...
int i; //local variable used for traversing vertices
int j;
/*header*/
printf("%-2s %-2s %-6s %-20s %-8s %-15s "
,"Vx"
,"TE"
,"Course"
,"Name"
,"Prereqs"
,"Successors");
//for loop used to traverse all vertices
for (i = 0; i < graph->iNumVertices; i++)
{
//in the terminal the segfault always kicks in here for some reason but I don't see any errors
//unless its passed a null graph which it isn't and it works fine in ddd
//prints the vertex, te, course id, course name
printf("%2d %2d %-6s %-20s "
,i+1
,0 //te
,graph->vertexM[i].szCourseId
,graph->vertexM[i].szCourseName);
//for loop used to traverse the prereqs of the specified vertex
//may need tweaking or reworking
for (e = graph->vertexM[i].prereqList; e != NULL; e = e->pNextEdge)
{
//prints the prereq
printf("%s "
,graph->vertexM[e->iPrereqVertex].szCourseId);
//iterate iCount to see if ... is needed to be printed
iCount++;
}
//conditional checking to see how many prereqs were printed
//if less than 4 prints the appropriate number of ...
if (iCount < 4)
{
for (j = iCount; j < 4; j++)
{
printf("... ");
}
}
//for loop to traverse successors
//may need tweaking or reworking
for (e = graph->vertexM[i].successorList; e != NULL; e = e->pNextEdge)
{
printf("%s "
,graph->vertexM[e->iSuccVertex].szCourseId);
}
printf(" ");
}
}
/*********************************/
/*******requires a findCourse call to pass in iVertex******
iVertex = findCourse(graph, szCourseId - what was grabbed from sscanf)*********/
void printOne(Graph graph, int iVertex)
{
EdgeNode *e; //local pointer variable used to traverse adjacency list
int iCount = 0; //local variable used for printing ...
int i;
/*header*/
printf("%-2s %-2s %-6s %-20s%-8s %-15s "
,"Vx"
,"TE"
,"Course"
,"Name"
,"Prereqs"
,"Successors");
//prints the vertex, te, courseId, courseName
printf("%2d %2d %-6s %-20s"
,iVertex+1
,0 //te
,graph->vertexM[iVertex].szCourseId
,graph->vertexM[iVertex].szCourseName);
//used to traverse prereqs
//may need tweaking or reworking
for (e = graph->vertexM[iVertex].prereqList; e != NULL; e = e->pNextEdge)
{
printf("%s "
,graph->vertexM[e->iPrereqVertex].szCourseId);
//increment iCount for each prereq
iCount++;
}
//if iCount < 4 print appropriate number of ...
if (iCount < 4)
{
for (i = iCount; i < 4; i++)
{
printf("... ");
}
}
//used to traverse succesor list
//may need tweaks or rework
for (e = graph->vertexM[iVertex].successorList; e != NULL; e = e->pNextEdge)
{
printf("%s "
,graph->vertexM[e->iSuccVertex].szCourseId);
}
printf(" ");
}
/*********************************/
void printSources(Graph graph)
{
int i; //local variable used to traverse all vertices
/*header*/
printf("%-6s %-20s "
,"Course"
,"Name");
//for loop to traverse all vertices
for (i = 0; i < graph->iNumVertices; i++)
{
//conditional if the vertex has no prereq print that vertex
if (graph->vertexM[i].prereqList->iPrereqVertex == -1)
{
printf("%-6s %-20s "
,graph->vertexM[i].szCourseId
,graph->vertexM[i].szCourseName);
}
}
}
/*********************************/
void printSinks(Graph graph)
{
int i; //local variable used to traverse all vertices
/*header*/
printf("%-6s %-20s "
,"Course"
,"Name");
//for loop to traverse all vertices
for (i = 0; i < graph->iNumVertices; i++)
{
//if the vertex has no successor print that vertex
if (graph->vertexM[i].successorList->iSuccVertex == -1)
{
printf("%-6s %-20s "
,graph->vertexM[i].szCourseId
,graph->vertexM[i].szCourseName);
}
}
}
/********************************************************************/
/*this function is an extreme work in progress this is just a basic approach
may need serious reworking*/
void printTraversal(Graph graph, int iVertex, int iIndent)
{
int i; //local varible used for indentations
EdgeNode *e; //local pointer variable used to traverse adjacency list
//for loop used to traverse successor list of specified vertex
for (e = graph->vertexM[iVertex].successorList; e != NULL;
e = e->pNextEdge)
{
//prints appropriate number of indentations
for (i = 0; i < iIndent; i++)
{
printf(" ");
}
printf("%-6s %-20s "
,graph->vertexM[e->iSuccVertex].szCourseId
,graph->vertexM[e->iSuccVertex].szCourseName);
//recursive call for printTraversals passing the graph the new vertex and the increased indent
//p->iSuccVertex may not be right
printTraversal(graph, e->iSuccVertex,iIndent+1);
}
}
=========================================================================
//insert.c
#define CRT SECURE NO WARNINGS 1
//include files
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include "cs2123p5.h"
int causesCycle(Graph graph, int iPrereqVertex, int iVertex)
{
if(iVertex == iPrereqVertex)
return TRUE;
EdgeNode *e; // EdgeNode for traversal
for (e = graph->vertexM[iVertex].successorList; e != NULL; e = e->pNextEdge)
{
if(causesCycle(graph, iPrereqVertex, e->iSuccVertex)) // e->iPrereqVertex is not correct but for now it prevents segfaults
return TRUE;
}
return FALSE;
}
void insertPrereq(Graph graph, int iPrereqVertex, int iCourseVertex)
{
EdgeNode *eNew = allocateEdgeNode(); //new node to be inserted
EdgeNode *eNew2 = allocateEdgeNode();
EdgeNode *eCurrent; //pointer to the current head of the list
eNew->iPrereqVertex = iPrereqVertex;
eNew->iSuccVertex = iCourseVertex;
eNew2->iPrereqVertex = iPrereqVertex;
eNew2->iSuccVertex = iCourseVertex;
//set the courseVertex prereqlist vertex to the ones passed
if (graph->vertexM[iCourseVertex].prereqList == NULL)// check if prereqList list already had Edges
{
graph->vertexM[iCourseVertex].prereqList = eNew;
eNew->pNextEdge = NULL;
}
else
{
//set eCurrent to head of list
eCurrent = graph->vertexM[iCourseVertex].prereqList;
//set eNew next edge to the current head
eNew->pNextEdge = eCurrent;
//make eNew the current head
graph->vertexM[iCourseVertex].prereqList = eNew;
//set eCurrents next edge to NULL
}
//set the prereqVertex successorlist vertex to the ones passed
if (graph->vertexM[iPrereqVertex].successorList == NULL) // check if successor list already had Edges
{
graph->vertexM[iPrereqVertex].successorList = eNew2;
eNew2->pNextEdge = NULL;
}
else
{
//set eCurrent to point to head of list
eCurrent = graph->vertexM[iPrereqVertex].successorList;
//set eNew next edge to current head
eNew2->pNextEdge = eCurrent;
//make eNew the new head
graph->vertexM[iPrereqVertex].successorList = eNew2;
//set eCurrent next edge to NULL
}
}
Graph newGraph()
{
// allocate memory for graph
Graph g = (Graph)malloc(sizeof(GraphImp));
// check if memory is available
if(g == NULL)
ErrExit(ERR_ALGORITHM, "No available memory for graph");
// mark the graph as empty
g->iNumVertices = 0;
// initialize the values of the vertex array to -1
memset(g->vertexM, -1, MAX_VERTICES);
return g;
}
EdgeNode * allocateEdgeNode()
{
// allocate memory for an edge node
EdgeNode *eNew;
eNew = (EdgeNode *) malloc(sizeof(EdgeNode));
// check if memory is available
if(eNew == NULL)
ErrExit(ERR_ALGORITHM, "No available memory for edge node");
// make this node's next edge NULL
eNew->pNextEdge = NULL;
// assign empty values
eNew->iPrereqVertex = -1;
eNew->iSuccVertex = -1;
return eNew;
}
==========================================================================
//chain.c
#define CRT SECURE NO WARNINGS 1
//include files
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include "cs2123p5.h"
int maxChain(Graph graph, int iVertex)
{
if(iVertex <= 0)
return 0;
EdgeNode *e;// does this have to be malloced too? i'm suddenly forgetting the nitty gritty details.... no its a local pointer variable
int iCount;
int iFirst;
// traverse to the adjacent vertices
//goes through successor lists
for (e = graph->vertexM[iVertex].successorList; e != NULL;
e = e->pNextEdge)
{
//within successor lists it takes each path
return(iCount += maxChain(graph, e->iSuccVertex));
//somehow this should be reset
//but no quite like this because if it has more
//than one successor it subracts too many
}
}
void printLongChains(Graph graph, int iVertex, int pathM[], int iLevel, int iLongLength)
{
if(iVertex < 0) // this condition isn't correct
return;
EdgeNode *e;
int i;
pathM[iLevel] = iVertex;// this reads current vertex into pathM
for (e = graph->vertexM[iVertex].successorList; e!= NULL;
e = e->pNextEdge)
{
printLongChains(graph, graph->vertexM[iVertex].successorList->iSuccVertex, pathM, iLevel+1, iLongLength);
// we want to be able to overwrite shorter paths
// without permanently increasing iLevel
if((iLevel+1) == iLongLength)
{
printf(" Longest chains beginning with %s ", graph->vertexM[pathM[0]].szCourseId); // this will always be 0
for(i = 0; i < iLevel; i++)
{
printf("%-8s", graph->vertexM[pathM[i]].szCourseId);
}
printf("%-8s ", graph->vertexM[pathM[iLevel]].szCourseId);
}
}
}
==============================================================================