zoukankan      html  css  js  c++  java
  • 【模板】拓扑排序

    (图论杀我)

    定义:

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

    其实就是对于一张有向图,按照入度大小从小到大排序。

    实现过程:

    简单讲就是对于任意状态,先找到一个入度为0的点,记录答案后把所有与它相连的的点的入度减一,重复这个过程即可。

    代码:

    #include<iostream>
    #include<vector>
    #include<queue>
    using namespace std;
    struct edge
    {
    int next,to; 
    edge(){}
    edge(int a,int b)
    {
        next=a;
        to=b; 
    }
    }e[1000001];
    int tot,in[100001],first[100001];//邻接表存图 
    void add_edges(int a,int b)
    {
        e[++tot]=edge(first[a],b);
        first[a]=tot;
        in[b]++; 
    }
    int n,m;
    int ans[100001];
    queue<int>q;//队列优化 
    int cnt;
    void tp(int n)
    {
        for(int i=1;i<=n;i++)
        {
            if(in[i]==0)
            q.push(i);
        }
        while(!q.empty())
        {
            int p=q.front();//每次找到最后一个入队的点(就是当前状态对应的答案) 
            q.pop();
            ans[cnt++]=p;//存储答案 
            for(int j=first[p];j;j=e[j].next)
            {
                in[e[j].to]--;
                if(in[e[j].to]==0)
                {
                    q.push(e[j].to);
                }
            }//删掉改点 
        }
    }
    int main()
    {
        cin>>n>>m;
        int A,B;
        for(int i=1;i<=m;i++)
        {
            cin>>A>>B;
            add_edges(A,B);
        }
        tp(n);
        for(int i=0;i<n;i++)
        {
            cout<<ans[i]<<" ";
        }
        return 0;
    } 

    例题点这里:(拓扑排序+dp) (这个稍微裸一点,小细节很多)

    CSP-S RP++!

  • 相关阅读:
    条款1:理解模板类型推导
    非受限联合体
    整型
    vector作为函数返回类型
    SQL Server数据库空间管理 (1)
    1085 PAT单位排行 (25 分
    1084 外观数列 (20 分)
    1083 是否存在相等的差 (20 分)
    1082 射击比赛 (20 分)
    1081 检查密码 (15 分)
  • 原文地址:https://www.cnblogs.com/Daz-Os0619/p/11709199.html
Copyright © 2011-2022 走看看