简单的回顾了一下拓扑排序,并做了几道题,在此做一下总结。
拓扑排序算法原理比较简单,但在实现上,给我提供了一种比较好用的技巧。
对这种需要判断环的存在的,需要区分历史遍历过的和现在正在遍历的。这里对进行了扩展,用来表示标记现在正在访问的路径,而访问结束标记为。当然,这个只能在中使用。
bool dfs(int node){
vis[node]=-1;
For(i,0,G[node].size()-1){
int u=G[node][i];
if(vis[u]==-1) return 0;
if(vis[u]==1) continue;
--deg[u];
if(!deg[u]) if(dfs(u)==0) return 0;
}
vis[node]=1;
return 1;
}
当然,用堆或者队列之类的也是可以进行维护的。不过对于判断是否有环的话,还是更适合。
下面来说一说具体的题目:
:模板题、
:在拓扑排序时,顺便递推一下,也比较简单。
:这一题是要先构造出图来,然后DAG图上dp。主要难点在于想出构造图。当时刚刚看到这道题时,还是有点懵逼的。这类不好直接处理关系的题,可以考虑预处理一下关系,通过转化到图上(或其他类型的结构),再进行处理。
:这题挺坑的,输出要求是保证顺序条件的同时,依次保证,,在前,而不是字典序的大小。最开始处理的时候,总是不自觉的处理成字典序了。但是字典序的处理提供了一个想法,字典序的处理是尽量保证小的在前,而如果要是,,在前,即保证大的尽量在后面,这也就是反向构图,保证大的尽量在前面,然后再倒序输出。
:这题的难度不大,可以考虑先反向构图,从每个被选中点去遍历,找出一个DAG图。然后在DAG图上拓扑排序得到答案。坑点在于判断无解的情况,最开始无解的情况在时,继续进行了,导致出了问题,最后使整个过程都出了点问题。
来源:CSDN
作者:South-twilight
链接:https://blog.csdn.net/qq_35776579/article/details/103933186