Kahn算法
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 100010;
int n, m, a, b;
vector<int> e[N], tp;
int din[N]; // 所有顶点入度
bool toposort()
{
queue<int> q;
for (int i = 1; i <= n; i++)
if (din[i] == 0)
q.push(i); // 维护入度为零的队列q
while (!q.empty())
{
int x = q.front();
q.pop();
tp.push_back(x); // 操作过的顶点进入tp序列
for (auto y : e[x])
if (--din[y] == 0)
q.push(y);
}
return tp.size() == n;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)
{
cin >> a >> b;
e[a].push_back(b); // 存在边a->b
din[b]++;
}
if (!toposort())
cout << -1;
else
for (auto x : tp)
cout << x << " ";
return 0;
}
DFS
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 100010;
int n, m, a, b;
vector<int> e[N], tp;
typedef enum
{
UNDISCOVERED,
DISCOVERED,
VISITED
} VStatus;
VStatus status[N] = {UNDISCOVERED};
bool dfs(int x)
{
status[x] == DISCOVERED;
for (int y : e[x])
{
if (status[y] == DISCOVERED) // 有环
return false;
else if (status[y] == UNDISCOVERED)
if (!dfs(y))
return false;
}
status[x] = VISITED;
tp.push_back(x);
return true;
}
bool toposort()
{
for (int x = 1; x <= n; x++)
if (status[x] == UNDISCOVERED)
if (!dfs(x))
return false;
reverse(tp.begin(), tp.end());
return true;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)
{
cin >> a >> b;
e[a].push_back(b);
}
if (!toposort())
cout << -1;
else
for (int x : tp)
cout << x << " ";
return 0;
}