拓扑排序

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;
}
posted @ 2025-07-05 17:21  张诗羽  阅读(8)  评论(0)    收藏  举报