一:深度优先遍历(dfs)
运用递归从后往前找,先递归到尽头找出度为零的点,不断插入到数组首即可。
使用了刘汝佳老师的代码,顺便还判断了是否有有向环。
#include <bits/stdc++.h>
using namespace std;
#define maxn 105
int matrix[maxn][maxn], vis[maxn], topo[maxn], n, m, t;
//-1 正在访问,判断是否有环。0 未访问 1 已访问
bool dfs(int u) {
vis[u] = -1;
for(int i = 1; i <= n; i++) {
if(matrix[u][i]) {
if(vis[i]<0) return false;
else if(!vis[i]&&!dfs(i)) return false;
}
}
vis[u] = 1;
topo[--t] = u;
return true;
}
bool toposort() {
t = n;
for(int i = 1; i <= n; i++) {
if(!vis[i])
if(!dfs(i)) return false;
}
return true;
}
int main() {
freopen("i.txt","r",stdin);
while (cin >> n >> m && (n || m)) {
memset(matrix, 0, sizeof(matrix));
memset(topo, 0, sizeof(topo));
int x, y;
for (int i = 0; i < m; i++) {
cin >> x >> y;
matrix[x][y] = 1;
}
if(toposort()) {
for(int i = 0; i < n; i++)
cout << topo[i] << " ";
}
}
}
二:Kahn模板
需要在建图的同时统计各个点的入度个数。然后每次取出入度为0的顶点删掉,并删掉和该点有关的边,需要维护一个入度为0的队列或者栈。
#include <bits/stdc++.h>
using namespace std;
#define maxn 105
int matrix[maxn][maxn], indegree[maxn], topo[maxn], n, m;
void toposort() {
int cnt = 0;
queue<int> queue1;
for(int i = 1; i <= n; i++) {
if(!indegree[i])
queue1.push(i);
}
while(!queue1.empty()) {
int temp = queue1.front(); queue1.pop();
topo[cnt++] = temp;
for(int i = 1; i <= n; i++) {
if(matrix[temp][i]) {
indegree[i]--;
if(!indegree[i])
queue1.push(i);
}
}
}
}
int main() {
freopen("i.txt","r",stdin);
while (cin >> n >> m && (n || m)) {
memset(matrix, 0, sizeof(matrix));
memset(indegree, 0, sizeof(indegree));
int x, y;
for (int i = 0; i < m; i++) {
cin >> x >> y;
matrix[x][y] = 1;
indegree[y]++;
}
toposort();
for(int i = 0; i < n; i++)
cout << topo[i] << " ";
}
}