学习笔记——拓扑排序
在有向图中,对所有节点进行排序,要求没有一个节点指向它前面的一个节点,这样的序列称为拓扑序。
如何求拓扑序
统计节点入度,每次取出当前入度为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号商品连边,若出现了环,则互相约束,无解,然后跑一遍拓扑排序就行了。