zoukankan      html  css  js  c++  java
  • 拓扑排序笔记

    一:定义:

    有向无环图(DAG)

    百度是这么说的:对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

    其实简单来讲,假设我们要学6本数学书 ,分别为数1,2,3,4,5,6

    给出相互之间的关系图:

    发现,数5,数6 的学习,依赖于数3,数4,而数3,4的学习又依赖于数1。不学数1,就不能学数3,4,5,6

    数4依赖于数1,2。不学数1+数2,就不能学数4

    所以给出几种学习顺序:

    1->2->3->4->5->6

    1->3->2->4->5->6

    2->1->4->3->5->6

    ......

    每一种学习顺序,都遵循图里的先后顺序,即不会对后续某本书的学习产生影响。

    即:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。

    二:找寻过程:

    借助于队列实现,另开数组ans[]记录进入队列的每个数

    1:记录有向边,记录每个点的入度。

    2:初始将所有入度为0的点进入队列。

    3:取队首,pop掉。遍历与它相邻的边,把指向它的有向边一个一个地删除。当删到入度为0了,加入到队列,继续执行3。

    如果bfs结束以后,ans[]里存的点数目<总的数目,说明存在环,无拓扑序列。

    三:板子题:

    Acwing:https://www.acwing.com/problem/content/850/

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    typedef pair<int,int>PII;
    const int maxn=1e5+10;
    int h[maxn],ne[maxn*2],e[maxn*2],idx;
    int n,m,tot=0;
    int d[maxn];//rudu
    int ans[maxn];
    void add(int a,int b)
    {    
        e[idx]=b;
        ne[idx]=h[a];
        h[a]=idx++;
    }
    bool bfs()
    {
        queue<int>q;
        for(int i=1;i<=n;i++)
        {
            if(d[i]==0)
            {
                q.push(i);
            }
        }
        while(!q.empty())
        {
            int t=q.front();
            ans[tot++]=t;
            q.pop();
            for(int i=h[t];i!=-1;i=ne[i])
            {
                int j=e[i];
                d[j]--;
                if(d[j]==0)
                {
                    q.push(j);
                }
            }
        }
        if(tot==n)
            return true;
        return false;
    }
    int main()
    {
        cin>>n>>m;
        memset(h,-1,sizeof(h));
        for(int i=1;i<=m;i++)
        {
            int a,b;
            cin>>a>>b;
            add(a,b);
            d[b]++;
        }
    //    bfs();
        if(bfs())
        {
            for(int i=0;i<tot;i++)
                cout<<ans[i]<<" ";
                cout<<endl;
        }
        else
        {
            puts("-1");
        }
    }

     四:拓展提高题:

  • 相关阅读:
    jmetal随机数
    [转]IDEA断点调试基础
    [转]java指数表示最大数和最小数
    反向学习相对基学习opposition-based learning简介
    IGD反转世代距离-多目标优化评价指标概念及实现
    matlab sum函数
    多目标优化拥挤距离计算
    [转]matlab 中的波浪号
    多目标优化按支配关系分层实现
    Matlab矩阵加入新元素
  • 原文地址:https://www.cnblogs.com/liyexin/p/13995874.html
Copyright © 2011-2022 走看看