• 基于dfs的拓扑排序


    基于dfs的拓扑排序

    以每一个入度为0的点为起点dfs,节点回溯时进栈(类似欧拉回路),有反向边说明有回路。

    img

    1. 首先2节点的邻接顶点是13,由于我们是DFS,它就会一条路走下去,所以先走左边,即到达1号节点
    2. 然后1号节点的邻接顶点是4,所以接下来箭头指向44是一个出度为0的节点,它没有邻接顶点,所以不用再往下递归,把4直接保存到栈中。
    3. 接着返回到1节点,此时1节点没有未访问的临界点,把1压入栈中
    4. 然后返回到2节点,接着走右边这条路,到达3号节点,接着从3号节点的邻接顶点出发,但是都已经访问过了,所以返回3后,直接把3压入栈中,最后返回2,把2压入栈中。
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 10005;
    stack<int> stk;
    struct edge{
        int to, nx;
    }e[maxn];
    int n, m, len, cycle, head[maxn], rd[maxn], vis[maxn];
    void insert(int x, int y){//插边
        e[++len].to = y;
        e[len].nx = head[x];
        head[x] = len;
    }
    void dfs(int u){
        if(cycle) return;//已经存在环
        vis[u] = -1;//标记当前点为起点
        for(int i=head[u]; i; i=e[i].nx){//遍历邻接点
            int v = e[i].to;
            if(!vis[v]) dfs(v);
            else if(vis[v] == -1){//如果回到了起点,说明存在环
                printf("Cycle
    ");
                cycle=1;
                return;
            }
        }
        vis[u] = 1;
        stk.push(u);
    }
    int main(){
        scanf("%d%d", &n, &m);
        for(int i=1; i<=m; i++){
            int x, y; scanf("%d%d", &x, &y);
            insert(x ,y);
            rd[y] ++;
        }
        for(int i=1; i<=n; i++) if(!rd[i]) dfs(i);//如果入度为0,开始dfs
        if(!cycle)//无环
            while(!stk.empty()){
                printf("%d ", stk.top());
                stk.pop();
            }
        return 0;
    }
    
  • 相关阅读:
    NAT基本原理及应用
    端口转发和端口映射的区别
    Xshell不能连接Kali系统SSH的解决
    PowerSploit
    powertool
    Windows/Linux 下反弹shell
    Apache Shiro 反序列化漏洞复现(CVE-2016-4437)
    渗透测试神器Cobalt Strike使用教程
    Notepad++ 小技巧
    Linux:Day44(上)
  • 原文地址:https://www.cnblogs.com/hzoi-poozhai/p/12780954.html
Copyright © 2020-2023  润新知