• 拓扑排序(topological sort)


    一、定义:

    对一个有向无环图(Directed Acyclic Graph简称DAG) G进行拓扑排序

    是将G中所有顶点排成一个线性序列

    使得图中任意一对顶点u和v

    若边(u,v)∈E(G)

    则u在线性序列中出现在v之前

    注意:

    有时候,这里的排序不是唯一的

    二、算法 O(V+E)

    有两种:入度表、dfs

    (一)、入度表  O(V+E):

    找出图中0入度的点

    依次在图中删除这些点

    于是再找删掉点之后的0入度的点

    然后再删除...再找点

    入度为0的点 用 队列

    图 用 邻接表

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    using namespace std;
    
    const int maxn = 10005;
    int n,m,cnt;//cnt存储ans数组的下标
    bool a[maxn][maxn];//邻接矩阵 
    int  edge[maxn],ans[maxn];//edge[i]第i个点的入度,ans答案队列 
    queue<int> q;
    
    void topo_sort()
    {
        for(int i = 1;i <= n;i++)
            if(!edge[i])
                q.push(i);//将所有入度为0的点加入队列中 
        while(!q.empty())
        {
            const int u = q.front();
            ans[++cnt] = u;
            q.pop();
            for(int i = 1;i <= n;i++)
                if(a[u][i])
                {
                    edge[i]--;
                    if(!edge[i])
                        q.push(i);
                } 
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            a[x][y] = 1;
            edge[y]++;
        }
        topo_sort();
        if(cnt < n)
        {
            printf("有环
    ");
            return 0;
        } 
        for(int i = 1;i <= n;i++)
            printf("%d ",ans[i]);
        return 0;
    }

    (二)、dfs O(n2

    (又要咕咕咕了...也不知道要咕多久qwq)

    (洛谷居然出了一片日报,嘎!)

     (dfs只能判断有没有还环??!(hushuobadao

    用一个int类型的visit数组 标记节点

    其中-1表示回到自己(即 产生了环) 这届return

    否则,跑一边这个图,跑完了就没有环

    //拓扑排序dfs(只判断是否有环
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 10005;
    int n,m;
    bool a[maxn][maxn];//邻接矩阵建图
    bool flag;//判断是否有环,有环就true 
    int vis[maxn];//标记节点,注意是int类型,因为要用到-1,1,0 
    
    void dfs(int k)
    {
        vis[k] = -1;//特殊标记
        for(int i = 1;i <= n;i++)
        {
            if(vis[i] == 0 && a[k][i] == true)
            {
                dfs(i);
                vis[i] = 1;
            }
            if(vis[i] == 1 && a[k][i] == true)
            {
                printf("有环
    ");
                flag = true;
                return;
            }
        } 
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            a[x][y] = true;
        } 
        dfs(1);
        if(!flag)
            printf("无环
    ");
        return 0;
    } 

    (我..算不算没gu很久wa.)

  • 相关阅读:
    Excel导入导出DataGridView
    博客开通第一天
    windows10 VM12 安装Mac OS X 10.11
    js判断IE浏览器及版本
    C# MD5 加密
    WindowsErrorCode
    localStorage,sessionStorage的使用
    js实现页面锚点定位动画滚动
    纯js实现页面返回顶部的动画
    HTML table固定表头
  • 原文地址:https://www.cnblogs.com/darlingroot/p/10786357.html
Copyright © 2020-2023  润新知