# The adjacency table is used to represent AOV network and judge whether it is a directed acyclic graph

1. Note: the idea in this code comes from s1mba. Worship the great God!

2. This code creates an adjacency table based on the adjacency matrix. The convenience of this is that in the adjacency matrix, we can intuitively show whether the two vertices are connected, and distinguish whether they are digraphs by whether they are symmetric matrices or not. This is very important when creating adjacent tables. Use if (g.arcs [i] [J] = = 1) to judge whether to create a new table node.

3. In addition, adding an entry field in to the vertex table of the adjacency table is also the finishing touch. This is to facilitate judging whether the node entry is 0, so as to decide whether to stack.

4. By the way, the stack container in STL library is used in this code, which is more convenient. Using array and subscript index to move around, the boundary conditions are very troublesome. Although arrays may be faster

5. We should think about the performance of topologicalsort in the adjacency table data structure. First traverse the adjacency list, put the content of nodes with a degree of 0 into the stack, and then select one by one from the stack. Use while (!ZeroDegreeNodeStack.empty()) as the loop condition, and start traversing from the linked list of nodes in the stack. The degree of each node in the subsequent linked list is --, and then judge whether it is 0. If it is 0, enter the stack.

6. During the above traversal, it should be noted that after the content of the node at the top of the stack is output, it is really necessary to output the stack, and then record the number of stack nodes cnt + +, but an auxiliary variable cur should be used to save the value of the element at the top of the stack for the initial conditions in the for loop.

7. Never put the stack.pop() operation behind the for loop, because this will cause the elements stacked in the for loop to be directly out of the stack and out of the stack before output, which is logically wrong!

## Upper Code:

```#include <iostream>
#include <stack>

using namespace std;
/**
* 1.Using adjacency matrix to create graph, but it is more convenient to use adjacency table because of the need to delete vertices in topology sorting
* Therefore, after we create the adjacency matrix of the graph, we use the adjacency matrix to create the adjacency table
* 2.Because we often need to judge whether the penetration of a node is 0, we add a data field in to the vertex table of the adjacency table
*/
#define MaxVertexNum 100
#define Infinity 10000

typedef	struct {
int vers[MaxVertexNum]; //vertex array
int arcs[MaxVertexNum][MaxVertexNum]; //Edge array
int vernum, arcnum; //Number of points and edges
}AMGraph;

//Table node structure definition of adjacency table
typedef struct EdgeNode {
int adjver; //Store the subscript of the adjacent node in the vertex table
struct EdgeNode* next; //Pointer field to the next adjacent node
}EdgeNode;

//Definition of vertex table structure of adjacency table
typedef struct {
int in; //indegree
int data; //The content of the storage node is the int value stored in the AOV network of this experiment
EdgeNode* firstEdge; //Pointer field to the first adjacent node

typedef struct {
int vernum, arcnum; //Number of vertices and edges
}adjlist, *AdjList; //The first one without a pointer is to allocate space

void CreatAM(AMGraph &G) { //Initialize adjacency matrix
cout << "Please enter the number of vertices and edges of the graph:" << endl;
cin >> G.vernum >> G.arcnum;
for (int i = 1; i <= G.vernum; i++) {
G.vers[i] = i;
}
for (int i = 1; i <= G.vernum; i++) {
for (int j = 1; j <= G.vernum; j++) {
G.arcs[i][j] = 0;
}
}
G.arcs = 1;
G.arcs = 1;
G.arcs = 1;
G.arcs = 1;
G.arcs = 1;
}

EdgeNode* p;
AL->vernum = G.vernum;
AL->arcnum = G.arcnum;
for (int i = 1; i <= G.vernum; i++) { //initialization
AL->adjverList[i].data = G.vers[i]; //Node information replication
}
for (int i = 1; i <= G.vernum; i++) {
for (int j = 1; j <= G.vernum; j++) {
if (G.arcs[i][j] == 1){ //If there are edges
p = new EdgeNode;
p->adjver = j; //The subscript of the adjacent node in the vertex table
AL->adjverList[j].in++; //Note that this is j!
}
}
}
}

EdgeNode* p;
int cnt = 0; //Count the number of deleted nodes to judge whether it is a directed acyclic graph
stack<int> ZeroDegreeNodeStack; //Stack with storage degree of 0
for (int i = 1; i <= AL->vernum; i++) {
ZeroDegreeNodeStack.push(i); //Put the content of the node on the stack
}
}
while (!ZeroDegreeNodeStack.empty()) {
cout << ZeroDegreeNodeStack.top() << "->"; //Output node content
int cur = ZeroDegreeNodeStack.top(); //Auxiliary variable
ZeroDegreeNodeStack.pop();
cnt++;
for (p = AL->adjverList[cur].firstEdge; p != NULL; p = p->next) {
if (AL->adjverList[p->adjver].in == 0) { //If you delete this node and the degree decreases by 1 and becomes 0, it will be put into the stack
}
}//for
}//while
cout << endl;
if (cnt == AL->vernum)
cout << "Should AOV Net is a directed acyclic graph!" << endl;
else
cout << "Should AOV A net is not a directed acyclic graph" << endl;
}

int main() {