zoukankan      html  css  js  c++  java
  • 【图论】拓扑排序

    算法一:

    寻找入度为0(没有任何结点指向它)的结点Q,删除Q及与Q相连的边。

    重复上述操作直到结点被全部删除,或找不到入度为0的结点(存在有向环,非DAG)。


    算法二:

    遍历每一个结点,通过DFS访问结点的所有子孙。当前结点无子孙时为递归边界,将结点加入到当前拓扑序的首部

    需要注意的是,要判断递归路上是否有遇到存在有向环的结点,故要用(vis[u])存储结点状态:

    (vis[u]=0)时,结点(u)从未访问过;

    (vis[u]=-1)时,结点(u)正在访问;

    (vis[u]=1)时,结点(u)已访问完毕。

    int E[1000 + 10][1000 + 10];
    int vis[100 + 10];
    int topo[100 + 10];
    int n, m, pos;
    bool dfs(int V) {
        vis[V] = -1;
        for (int u = 1;u <= n;u++) {
            if (E[V][u]) {
                if (vis[u] < 0) return false;//存在有向环
                else if (!vis[u] && !dfs(u)) return false;//没访问过的新结点进行访问,但过程中出现有向环
            }
        }
        vis[V] = 1;
        topo[pos] = V;
        pos--;
        return true;
    }
    
    bool toposort() {
        for (int u = 1;u <= n;u++) {
            if (!vis[u] && !dfs(u))return false;
        }
        return true;
    }
    
    int main()
    {
        while (cin >> n >> m) {
            if (!n && !m) break;
            memset(E, 0, sizeof(E));
            memset(topo, 0, sizeof(topo));
            memset(vis, 0, sizeof(vis));
            pos = n;
            for (int i = 1;i <= m;i++) {
                int a, b;
                cin >> a >> b;
                E[a][b] = 1;
            }
            if (toposort()) {
                cout << topo[1];
                for (int i = 2;i <= n;i++) cout << " " << topo[i];
                cout << endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    HTML5学习小结
    HTML和CSS的复习总结
    LOL UVALive
    E
    D
    C
    B
    D
    J
    css
  • 原文地址:https://www.cnblogs.com/streamazure/p/12664250.html
Copyright © 2011-2022 走看看