题目描述:
This is a problem given in the Graduate Entrance Exam in 2018: Which of the following is NOT a topological order obtained from the given directed graph? Now you are supposed to write a program to test each of the options.

输入格式:
Each input file contains one test case. For each case, the first line gives two positive integers N (≤ 1,000), the number of vertices in the graph, and M (≤ 10,000), the number of directed edges. Then M lines follow, each gives the start and the end vertices of an edge. The vertices are numbered from 1 to N. After the graph, there is another positive integer K (≤ 100). Then K lines of query follow, each gives a permutation of all the vertices. All the numbers in a line are separated by a space.
输出格式:
Print in a line all the indices of queries which correspond to “NOT a topological order”. The indices start from zero. All the numbers are separated by a space, and there must no extra space at the beginning or the end of the line. It is graranteed that there is at least one answer.
样例输入:
6 8
1 2
1 3
5 2
5 4
2 3
2 6
3 4
6 4
5
1 5 2 3 6 4
5 1 2 6 3 4
5 1 2 3 6 4
5 2 1 6 3 4
1 2 3 4 5 6
样例输出:
3 4
题意:
给出n个结点和m条有向边,现有k个查询序列,记录那些不是拓扑序列的序列编号,并在最后输出。
思路:
遍历这个查询序列的每个元素,如果这个元素的入度为0,说明到这一步没有问题,那么把这个元素连通的结点的入度减1;如果入度不为0,说明这不是一个拓扑序列。(类似一个学习课程的顺序,拓扑排序是一个合理的顺序,即当你学习这门课程时,前面相关的课程一定是学完了的,这里的不为0说明前面还有相关课程没有学习,所以顺序不对)
参考代码:
#include <stdio.h>
#include <vector>
using namespace std;
const int maxn = 1010;
int n, m, k; //结点数,路径数,查询数
vector<int> G[maxn]; //路径
int inDegree[maxn] = {0}, tempDegree[maxn]; //入度
vector<int> notTopo; //记录不是拓扑序列的序列
int main(){
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++){
int st, ed;
scanf("%d%d", &st, &ed);
G[st].push_back(ed);
inDegree[ed]++;
}
scanf("%d", &k);
for(int i = 0; i < k; i++){
for(int j = 1; j <= n; j++){
tempDegree[j] = inDegree[j];
}
vector<int> seq(n);
for(int j = 0; j < n; j++){
scanf("%d", &seq[j]);
}
for(int j = 0; j < n; j++){
int num = seq[j];
if(tempDegree[num] == 0){
int len = G[num].size();
for(int z = 0; z < len; z++){
int arr = G[num][z];
tempDegree[arr]--;
}
}else{
notTopo.push_back(i);
break;
}
}
}
int nLen = notTopo.size();
for(int i = 0; i < nLen; i++){
if(i != 0) printf(" ");
printf("%d", notTopo[i]);
}
return 0;
}
本文详细解析了2018年研究生入学考试中的一道拓扑排序问题,通过遍历查询序列并检查结点入度的方式,判断哪些序列不是有效的拓扑排序。文章提供了完整的参考代码,帮助读者理解解决问题的具体步骤。

被折叠的 条评论
为什么被折叠?



