/* Time limit: 4000ms 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> 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; } // Queue ADT struct queueNode { int id; // each node in the Queue contains an ID struct queueNode* next; struct queueNode* prev; }; typedef struct queueNode* QueueNode; struct queue { int capacity; QueueNode head; QueueNode tail; int size; }; typedef struct queue* QueueADT; QueueNode AllocateEmptyQueueNode() { QueueNode newNode = (QueueNode) malloc(sizeof(struct queueNode)); newNode->id = -1; newNode->next = NULL; newNode->prev = NULL; return newNode; } QueueADT CreateQueue(int capacity) { QueueADT q = (QueueADT) malloc(sizeof(struct queue)); q->capacity = capacity; q->size = 0; q->head = AllocateEmptyQueueNode(); q->tail = AllocateEmptyQueueNode(); q->head->next = q->tail; q->tail->prev = q->head; return q; } int IsEmpty(QueueADT q) { return q->size == 0; } int IsFull(QueueADT q) { return q->size == q->capacity; } void Enqueue(QueueADT q, int id) { if (q->size < q->capacity) { QueueNode tmp = AllocateEmptyQueueNode(); tmp->id = id; QueueNode prev = q->tail->prev; prev->next = tmp; tmp->prev = prev; tmp->next = q->tail; q->tail->prev = tmp; q->size++; } } int Dequeue(QueueADT q) { if (!IsEmpty(q)) { q->size--; int v; QueueNode tmp = q->head->next; q->head->next = tmp->next; tmp->next->prev = q->head; v = tmp->id; free(tmp); return v; } else { return -1; } } void FreeQueue(QueueADT q) { QueueNode tmp = q->head; while (tmp != NULL) { QueueNode next = tmp->next; free(tmp); tmp = next; } free(q); } // 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; } // The test data guarantee that there does not exist self-loop or multiple occurrence of the same edge at any time point. void AddEdge(GraphADT myGraph, int u, int v) { // WRITE YOUR CODE HERE } void DeleteEdge(GraphADT myGraph, int u, int v) { // WRITE YOUR CODE HERE } // check whether there is path from u to v. If there is a path, return 1. Otherwise, return 0. // please use BFS to check whether there is a path from u to v // If there is a path, return 1. Otherwise, return 0. int Query(GraphADT myGraph, int u, int v) { QueueADT myQueue = CreateQueue(myGraph->n); int* color = (int*) malloc(myGraph->n * sizeof(int)); memset(color, 0, myGraph->n * sizeof(int)); // 0 means white, 1 means gray, 2 means black color[u] = 1; Enqueue(myQueue, u); // Remember to free the memory of the queue and the color array before returning the answer // WRITE YOUR CODE HERE } OP get_op() { char str[20]; scanf("%s", str); if (strcmp(str, "add") == 0) { return ADD; } else if (strcmp(str, "delete") == 0) { return DELETE; } else if (strcmp(str, "query") == 0) { return QUERY; } else { return ERROR_OP; } } int main() { int n, u, v; scanf("%d", &n); GraphADT myGraph = CreateGraph(n); scanf("%d", &n); for(int i=0; i<n; i++) { switch (get_op()) { case ADD: scanf(" %d%d", &u, &v); AddEdge(myGraph, u, v); break; case DELETE: scanf(" %d%d", &u, &v); DeleteEdge(myGraph, u, v); break; case QUERY: scanf(" %d%d", &u, &v); if (Query(myGraph, u, v)) { printf("1\n"); } else { printf("0\n"); } break; default: printf("Error Input\n"); } } } ---------------------------------------End of Code--------------------------------------- ## [Graph ADT and BFS] You are tasked to implement the graph ADT, which is a directed unweighted graph, using adjacency list. This graph ADT supports 3 following operations, assuming that the number of nodes is known. The graph ADT in this problem needs to support three operations: - 1. AddEdge(u, v): add an edge to the graph - 2. DeleteEdge(u, v): delete an edge from the graph - 3. Query(u, v): use BFS to check whether there is a path from u to v. If there is a path, report 1. Otherwise, report 0. The test data guarantee that there does not exist self-loop or multiple occurrence of the same edge at any time point. ### Input The first line contains two integers $n, m(1\leq n\leq 3000, 1\leq m \leq 10^6)$, representing the number of nodes and operations. The next $m$ lines each represent an operation: - 1. add u v : add an directed an edge from $u$ to $v$. - 2. delete u v : delete an edge (u,v) from the graph. If the edge does not exist in the graph, do nothing. - 3. query u v : check whether there is a path from u to v. If there is a path, report '1'. Otherwise, report '0'. where $0\leq u,v < n$. ### Output For each query operation, output one integer in a single line. If there is a path, output '1'. Otherwise, output '0'. ### Example **Input** ``` 6 11 add 1 2 add 2 3 query 1 3 query 3 1 add 5 3 add 3 4 query 5 4 delete 1 2 query 1 4 add 1 5 query 1 4 ``` **Output** ``` 1 0 1 0 1 ```