学习笔记——拓扑排序

在有向图中,对所有节点进行排序,要求没有一个节点指向它前面的一个节点,这样的序列称为拓扑序。

如何求拓扑序

统计节点入度,每次取出当前入度为0的点,将其与其相连的边删除,重复执行。

当某一时刻找不到入度为0的点,要么已经找完了所有节点,要么是有环无解。

\(code:\)

queue<int> q;
vector<int> ans;
void topsort(){
    for(int i=1;i<=n;i++)
        if(in[i]==0)
            q.push(i);
    while(q.size()){
        int x=q.front();
        q.pop();
        ans.push_back(x);
        for(int i=Last[x];i;i=Next[i]){
            int y=End[i];
            in[y]--;
            if(in[y]==0){
                q.push(y);
            }
        }
    }
    if(ans.size()==n){
        for(auto it:ans){
            printf("%d ",*it):
        }
        printf("\n");
    }
    else printf("-1");//有环无解
}

注意:有些情况下可能会有多个拓扑序,当题目要求字典序最小时,将队列换成优先队列即可。

总结:

拓扑排序是对有向图节点进行排序的算法,其限制是对于序列中任意元素,前面都没有被它所指向的点。

举个例子:

商店有\(N\)个物品,但其中购买一些物品需要先购买其他的物品才能解锁购买,求一个合法购买方案。

将有前提条件的商品向所限制商品连边,例如:购买1号商品得先购买2,3号商品,所以将1号商品向2,3号商品连边,若出现了环,则互相约束,无解,然后跑一遍拓扑排序就行了。

posted @ 2021-11-14 12:47  Thermalrays  阅读(43)  评论(0编辑  收藏  举报