zoukankan      html  css  js  c++  java
  • 拓扑排序(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.)

  • 相关阅读:
    阿里P8架构师谈:阿里双11秒杀系统如何设计?
    秒杀系统设计的知识点
    秒杀系统架构优化思路
    秒杀系统解决方案
    Entity Framework Code First (七)空间数据类型 Spatial Data Types
    Entity Framework Code First (六)存储过程
    Entity Framework Code First (五)Fluent API
    Entity Framework Code First (四)Fluent API
    Entity Framework Code First (三)Data Annotations
    Entity Framework Code First (二)Custom Conventions
  • 原文地址:https://www.cnblogs.com/darlingroot/p/10786357.html
Copyright © 2011-2022 走看看