Cycle Detection

/*
Time limit: 1000ms
Memory limit: 256mb

---------------------Copy the following code, complete it and submit---------------------
I, <Your Full Name>, am submitting the assignment for
an individual project.
I declare that the assignment here submitted is original except for
source material explicitly acknowledged, the piece of work, or a part
of the piece of work has not been submitted for more than one purpose
(i.e. to satisfy the requirements in two different courses) without
declaration. I also acknowledge that I am aware of University policy
and regulations on honesty in academic work, and of the disciplinary
guidelines and procedures applicable to breaches of such policy and
regulations, as contained in the University website
http://www.cuhk.edu.hk/policy/academichonesty/.
It is also understood that assignments without a properly signed
declaration by the student concerned will not be graded by the
teacher(s).
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

typedef enum {ADD = 1, DELETE, QUERY, ERROR_OP} OP;

// this linked list has no head or tail, which means that if this list is empty, then it equals NULL
struct linkedListNode {
    int id;
    struct linkedListNode* next;
};

typedef struct linkedListNode* ListNode;

ListNode CreateNode(int id) {
    ListNode node = (ListNode) malloc(sizeof(struct linkedListNode));
    node->id = id;
    node->next = NULL;

    return node;
}

// Stack ADT
struct stack {
    int capacity;
    int* arr;
    int size;
};

typedef struct stack* StackADT;

// Create a stack with the given capacity
// The stack is empty when it is created
StackADT CreateStack(int capacity) {
    StackADT s = (StackADT) malloc(sizeof(struct stack));
    s->arr = (int*) malloc(capacity * sizeof(int));
    s->capacity = capacity;
    s->size = 0;
    return s;
}

// Check if the stack is empty
// If the stack is empty, return 1, otherwise return 0
int IsEmpty(StackADT s) {
    return s->size == 0;
}

// push the value into the stack
// If the stack is full, do nothing
void Push(StackADT s, int value) {
    if (s->size < s->capacity) {
        s->arr[s->size++] = value;
    }
}

// Pop the top element of the stack
// If the stack is empty, do nothing
void Pop(StackADT s) {
    if (!IsEmpty(s)) {
        s->size--;
    }
}

// Get the top element of the stack
int Top(StackADT s) {
    return s->arr[s->size-1];
}

// Free the stack
void FreeStack(StackADT s) {
    free(s->arr);
    free(s);
}
// graph

// We use array to maintain nodes instead of the hashTables.
// For example, G[i] is exactly the adjacency list of the node i
struct graph {
    int n;
    ListNode* G;
};

typedef struct graph* GraphADT;

GraphADT CreateGraph(int n) {
    GraphADT myGraph = (GraphADT) malloc(sizeof(struct graph));
    myGraph->n = n;
    myGraph->G = (ListNode*) malloc(n * sizeof(ListNode));
    memset(myGraph->G, 0, n * sizeof(ListNode));

    return myGraph;
}

// Free the graph
void FreeGraph(GraphADT myGraph) {
    for(int i = 0; i < myGraph->n; i++) {
        ListNode node = myGraph->G[i];
        while(node != NULL) {
            ListNode temp = node;
            node = node->next;
            free(temp);
        }
    }
    free(myGraph->G);
    free(myGraph);
}

// In our test case, each edge is only added once
void AddEdge(GraphADT myGraph, int u, int v) {
    // WRITE YOUR CODE HERE

}

// Use DFS to detect cycle in the graph
// If the graph is acyclic, return FALSE
// If the graph is cyclic, return TRUE
bool DetectCycle(GraphADT myGraph) {
    StackADT myStack = CreateStack(myGraph->n);
    int* color = (int*) malloc(myGraph->n * sizeof(int));
    memset(color, 0, myGraph->n * sizeof(int));
    // Color 0 means white, 1 means gray, 2 means black

    int* discovery_time = (int*) malloc(myGraph->n * sizeof(int));
    memset(discovery_time, 0, myGraph->n * sizeof(int));
    int* finish_time = (int*) malloc(myGraph->n * sizeof(int));
    memset(finish_time, 0, myGraph->n * sizeof(int));

    // Remember to free the memory of the stack and the color array
    // and the discovery_time and finish_time arrays right before returning the answer
    // FreeStack(myStack);
    // free(color);
    // free(discovery_time);
    // free(finish_time);

    // WRITE YOUR CODE HERE

}

int main() 
{
    int T, n, m, u, v;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        GraphADT myGraph = CreateGraph(n);

        scanf("%d", &m);
        for(int i = 0; i < m; i++)
        {
            scanf("%d %d", &u, &v);
            AddEdge(myGraph, u, v);
        }

        int Cycle_Tag = DetectCycle(myGraph);

        if(Cycle_Tag == 0) {
            printf("The graph is acyclic.\n");
        } else {
            printf("The graph is cyclic.\n");
        }
        FreeGraph(myGraph);
    }

    return 0;
}


---------------------------------------End of Code---------------------------------------

## [Cycle Detection]

You are given multiple directed unweighted graphs. 

For each graph, determine if it is a Directed Acyclic Graph (DAG) or contains a cycle.

You also need to implement the Graph ADT with adjacency list.

The data guarantee that there is no self-loop in the graph.

### Input

The first line contains an integer $T(1\leq T\leq 5)$, representing the number of directed unweighted graphs.

For each graph, the first line contains two integers $n, m(1\leq n\leq 100000, 1\leq m \leq 2\times 10^5)$, representing the number of nodes and edges in the graph.

The next $m$ lines each contain two integers $u, v(0\leq u, v < n)$, denoting a directed edge from u to v.

### Output

For each directed unweighted graph:

 - Output "The graph is acyclic." if it is a DAG.

 - Output "The graph is cyclic." if it contains a cycle.

### Example
**Input**
```
3
2 2
1 0
0 1
4 5
0 1
1 2
0 3
1 3
2 3
5 5
1 2
2 4
4 0
0 3
0 2
```

**Output**
```
The graph is cyclic.
The graph is acyclic.
The graph is cyclic.
```


Submit