Fake code:
while (find the i-th node with zero in-degree) { indegree[ith batch of nodes]; Output the i-th batch of nodes as a semester's course; indegree[all nodes pointed to by the i-th batch of nodes]--; }Encapsulate the variables and functions needed to solve the problem in a class
class course//course类 { public: course(int n=1) {//Define the constructor of the course class num=n indegree=new int[n+1]; edge=new vector<int>[n+1]; memset(indegree,0,sizeof(int)*(n+1));//Set the indegree array to zero } void getIndegree();//Get the in-degree of each node according to the input set of preceding classes, and put it into the array indegree void topologicalSort();//Topological sort to get the courses of each semester private: stack<int> zeroInd;//Used to record each batch of nodes with zero in-degree int *indegree;//Record the in-degree of each node int num;//Record the number of courses vector<int> *edge;//Record the next node pointed to by each node bool findZeroInD();//Private function, find the node with zero in-degree and put it on the stack zeroInd };At the beginning, I did not introduce the course class, but directly defined the global arrays indegree and edge. To zero the indegree array only needs to be
int indegree[200]={0};After the introduction of the course class, dynamic allocation of memory space is used
indegree=new int[n+1]; edge=new vector<int>[n+1];
It is necessary to use the memset function to zero it. At the beginning, I directly memset(indegree,0,sizeof(indegree)); and found that I could not get the correct result. Later, I thought that the problem lies in sizeof(indegree), because at this time indegree is used as an int pointer variable, not as an array, so sizeof(indegree) should be the size of int* type variable at this time, generally four bytes, Instead of equal to the size of the memory space we allocated, if you want to represent the size of the allocated memory space, you need sizeof(int)*(n+1), change to memset(indegree,0,sizeof(int)*(n+ 1)); the correct result can be obtained. Some people may doubt that the correct result can be obtained by using sizeof (array name) before, that is because the array name is declared at the beginning, such as int a[10];, and in this question, indegree is actually int type of pointer.
The implementation of each member function is given below
void course::getIndegree() { int x,y; while(scanf("%d%d",&x,&y)==2) { if(x==y) continue; edge[x].push_back(y); indegree[y]++; //printf("%d %d %d\n",x,y,indegree[y]); } } bool course::findZeroInD() { int cnt=0; for(int i=1;i<=num;i++) { if(!indegree[i]) { //printf("%d\n",i); zeroInd.push(i); indegree[i]--; cnt++; } } return cnt!=0; } void course::topologicalSort() { int semester=1,cnt=num; while(findZeroInD()) { printf("Semester %d :\n",semester++); int t; while(!zeroInd.empty()) { t=zeroInd.top();zeroInd.pop();cnt--; printf("%d ",t); for(int i=0;i<edge[t].size();i++) { indegree[edge[t][i]]--; } } putchar('\n'); } if(cnt==0) printf("At least %d semesters are required\n",semester-1); else printf("There are %d courses remaining, there is a closed loop in the previous class schedule\n",cnt); }
After understanding the idea of topological sorting, it is not difficult to understand the above function implementation process. The only thing to note is that I added a judgment on whether there is a closed loop in the previous class schedule in the topologicalSort() function, and added a counter cnt. Every time I get a node with zero in-degree, I will cnt--. If the last cnt is If it is zero, the class schedule is a DAG, and the topological sequence can be obtained. Otherwise, there is a closed loop in the graph, and the topological sequence cannot be obtained.
The main function and test data are given below
intmain() { int n; freopen("data.txt","r",stdin); scanf("%d",&n); course c(n); c.getIndegree(); c.topologicalSort(); return 0; }
//data.txt 8 1 2 3 4 2 5 3 6 1 5 7 8 8 1 1 3