PAT甲级1146Topological Order
题目链接
https://pintia.cn/problem-sets/994805342720868352/problems/994805343043829760
题解
题目要求
给定一个有向图,请判断一个序列是否是该有向图的拓扑序列。
-
输入
- N:正整数,不超过1000,图中顶点的数量,顶点索引为[1,N]
- M:正整数,不超过10000,有向边的数量
- M条有向边:开始顶点索引、结束顶点索引
- K:不超过100,待检验的序列的个数
- K个序列:索引为[0,K]
-
输出
对于每个排列,如果不是拓扑排序则输出其索引
解题思路
- 保存每个结点的前驱结点
- 使用一维数组保存每个结点是否已访问
- 遍历序列判断每个结点的前驱结点是否已访问,如果未访问,则该序列不是拓扑序列
代码
// Problem: PAT Advanced 1146
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805343043829760
// Tags: 拓扑序列 图
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> before;
int main()
{
int n, m, k;
scanf("%d %d", &n, &m);
before.resize(n+1);
int v1, v2;
for (int i = 0; i < m; i++){
scanf("%d %d", &v1, &v2);
before[v2].push_back(v1);
}
scanf("%d", &k);
vector<int> result;
for (int i = 0; i < k; i++){ // 判断k个序列
// 保存一个序列
vector<int> sequence(n);
for (int j = 0; j < n; j++){
scanf("%d", &sequence[j]);
}
// 判断该序列是否是拓扑序列
vector<bool> visited(n + 1, false);
bool isTopological = true;
for (int j = 0; j < n; j++){
v2 = sequence[j];
for (auto iter = before[v2].begin(); iter != before[v2].end(); iter++){
if (!visited[*iter]){
isTopological = false;
result.push_back(i);
break;
}
}
if (isTopological)
visited[v2] = true;
else
break;
}
}
// 输出结果
auto iter = result.begin();
printf("%d", *iter);
iter++;
while (iter != result.end()){
printf(" %d", *iter);
iter++;
}
printf("\n");
return 0;
}
作者:@臭咸鱼
转载请注明出处:https://www.cnblogs.com/chouxianyu/
欢迎讨论和交流!