C++代码
#include <cstring>
#include <iostream>
using namespace std;
const int N = 1010, M = 10010;
int h[N], ne[M], e[M], idx;
int q[N];
int d[N], temp[N], dd[N];
int n, m;
void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; }
bool judgeTop(){
// for(int i = 0; i < n; ++i) printf("%d ", q[i]);
// cout << endl;
if(d[q[0]] != 0) return false;
int hh = 0, tt = n - 1;
while(hh <= tt){
int t = q[hh++];
// for(int i = 1; i <= n; ++i) cout << d[i] << " ";
// cout << endl;
for(int i = h[t]; i != -1; i = ne[i]){
int j = e[i];
d[j]--;
}
//若此时发现t还有入度,说明p序列与拓扑顺序矛盾。
if(d[t] > 0) return false;
}
// for(int i = 1; i <= n; ++i) cout << d[i] << " ";
// cout << endl;
return true;
}
void copy(int des[], int source[]){
for(int i = 1; i <= n; ++i)
des[i] = source[i];
}
int main() {
cin >> n >> m;
memset(h, -1, sizeof h);
for (int i = 0; i < m; ++i) {
int a, b;
cin >> a >> b;
add(a, b);
d[b]++;
}
copy(temp, d);
int k;
cin >> k;
for (int i = 0; i < k; ++i) {
for(int j = 0; j < n; ++j) cin >> q[j];
// printf("%d\t", i);
// for(int mm = 0; mm < n; ++mm) printf("%d ", q[mm]);
// cout << endl;
if(!judgeTop()) cout << i << ' ';
copy(d, temp);
}
return 0;
}
这题考察拓扑结构的定义
按照定义,遍历序列中每个节点h,将h能摸到的节点i的入度-1(代表h能走向i)
如果满足定义,节点i的入度一定是0,否则就不满足定义
wiki解释如下:
例如,图形的顶点可以表示要执行的任务,并且边可以表示一个任务必须在另一个任务之前执行的约束;在这个应用中,拓扑排序只是一个有效的任务顺序。
当且仅当图中没有定向环时(即有向无环图),才有可能进行拓扑排序。
在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足下列条件时,才能称为该图的一个拓扑排序(英语:Topological sorting):
1、序列中包含每个顶点,且每个顶点只出现一次;
2、若A在序列中排在B的前面,则在图中不存在从B到A的路径。
清爽版本,上面那个版本保留了debug注释代码
#include <cstring>
#include <iostream>
using namespace std;
const int N = 1010, M = 10010;
int h[N], ne[M], e[M], idx;
int q[N];
int d[N], temp[N], dd[N];
int n, m;
void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; }
bool judgeTop(){
if(d[q[0]] != 0) return false;
int hh = 0, tt = n - 1;
while(hh <= tt){
int t = q[hh++];
for(int i = h[t]; i != -1; i = ne[i]){
int j = e[i];
d[j]--;
}
//若此时发现t还有入度,说明p序列与拓扑顺序矛盾。
if(d[t] > 0) return false;
}
return true;
}
void copy(int des[], int source[]){
for(int i = 1; i <= n; ++i)
des[i] = source[i];
}
int main() {
cin >> n >> m;
memset(h, -1, sizeof h);
for (int i = 0; i < m; ++i) {
int a, b;
cin >> a >> b;
add(a, b);
d[b]++;
}
copy(temp, d);
int k;
cin >> k;
for (int i = 0; i < k; ++i) {
for(int j = 0; j < n; ++j) cin >> q[j];
if(!judgeTop()) cout << i << ' ';
copy(d, temp);
}
return 0;
}