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

    1.什么是拓扑排序

      拓扑排序就是对有向无环图(DAG)上的一些点的编号进行排序,使得图中每条边的起点都比终点的位置要靠前

    前置知识:度

    一个点连着的边的数量,称为该点的度。其中由该点出发的称为出度,到达该点的称为入度。

    2.如何实现

      算法过程:

     

    1. 先统计所有点的入度,分离出入度为0的点,将其存到答案队列中,然后将这个点有边指向的所有的点的入度都减一
    2. 重复上述操作,直到没有点入度为零
    3. 如果还有点入度不为零,就说明有环,则问题无解

    比如这个图

    我们发现点1入度为0,所以分离点1,并对其他点的入度进行调整

    此时我们发现点2和4入度为0,那么我们先分离点2,调整入度

    继续分离

                          

     有环的情况:

    我们发现无论如何都没有点的入度为1,此时拓扑序无解

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int MAXN=9999999;
    
    int head[MAXN],to[MAXN],nxt[MAXN],in[MAXN],cnt;
    int ans[MAXN],nodecnt;
    
    inline void add(int u,int v) 
    {
        cnt++;
        to[cnt]=v;
        nxt[cnt]=head[u];
        head[u]=cnt;
    }
    
    int n,m;
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int start,end;
            scanf("%d%d",&start,&end);
            add(start,end);
            in[end]++;
        }
        priority_queue<int,vector<int>,greater<int> > q;
        for(int i=1;i<=n;i++)
        {
            if(!in[i]) q.push(i);
        }
        while(!q.empty())
        {
            int top=q.top();
            q.pop();
            ans[++nodecnt]=top;
            for(int e=head[top];e;e=nxt[e])
            {
                in[to[e]]--;
                if(!in[to[e]]) q.push(to[e]);
            }
        }
        if(nodecnt!=n) printf("No Solution");
        else 
        {
            for(int i=1;i<=nodecnt;i++)
            {
                printf("%d ",ans[i]);
            }
        }
        
    }
  • 相关阅读:
    Token的生成和检验
    MD5和SHA加密实现
    服务器读取客户端数据
    服务器上传和下载文件
    NOI模拟题4 Problem B: 小狐狸(fox)
    NOI模拟题4 Problem A: 生成树(mst)
    混凝土数学第四章之数论学习笔记
    混凝土数学第二章和式之有限微积分 ( 离散微积分 ) 学习笔记
    网络流相关学习笔记
    NOI模拟题1 Problem A: sub
  • 原文地址:https://www.cnblogs.com/lcezych/p/11049405.html
Copyright © 2011-2022 走看看