/*
*/
把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【模板】拓扑排序

(图论杀我)

定义:

对一个有向无环图(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++!

 

posted @ 2019-10-31 21:59  Kyoko_Yosa  阅读(175)  评论(1编辑  收藏  举报
浏览器标题切换
浏览器标题切换end