拓扑排序模板题,参考紫书。
使用邻接矩阵建图,开一个vis数组记录节点是否被访问。
从第一个节点开始遍历,只要此节点未被访问过,则对其进行dfs。
dfs过程中,先对正在访问的节点记录为-1,则当后面dfs深入时,遇到指向的节点vis值为-1,则出现了环图,返回false,并逐层将false返回,每个节点的所有后继访问结束时,将vis值置为1,即已经被访问,之后到达dfs最深层次即为拓扑排序的尾部节点,并且如此层层搭建到顶端。
#include <iostream>
#include <cstring>
#define maxn 105
using namespace std;
bool map[maxn][maxn];
int res[maxn], check[maxn], n, m, tot;
bool dfs(int x)
{
check[x] = -1;
//cout << x << endl;
for (int v = 1; v <= n; v++)
if (map[x][v])
{
if (check[v] < 0)
return false;
else if (!check[v])
if (!dfs(v))
return false;
}
check[x] = 1;
res[tot--] = x;
//cout << x << endl;
return true;
}
bool toposort()
{
tot = n;
memset(check, 0, sizeof check);
for (int i = 1; i <= n; i++)
{
if (!check[i])
if (!dfs(i))
return false;
}
return true;
}
int main()
{
while (cin >> n >> m)
{
if (!n && !m) break;
for (int i = 0; i <= n; i++)
for (int j = 0; j <= n; j++)
map[i][j] = 0;
for (int i = 0; i < m; i++)
{
int x, y;
cin >> x >> y;
map[x][y] = 1;
}
toposort();
cout << res[1];
for (int i = 2; i <= n; i++)
cout << ' ' << res[i];
cout << endl;
}
return 0;
}