拓扑排序

孤街醉人 提交于 2020-01-11 13:09:13

简单的回顾了一下拓扑排序,并做了几道题,在此做一下总结。

拓扑排序算法原理比较简单,但在实现上,给我提供了一种比较好用的技巧。

对这种需要判断环的存在的,需要区分历史遍历过的和现在正在遍历的。这里对vis[]vis[]进行了扩展,用1-1来表示标记现在正在访问的路径,而访问结束标记为11。当然,这个只能在dfsdfs中使用。

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;
}

当然,用堆或者队列之类的也是可以进行维护的。不过对于判断是否有环的话,还是dfsdfs更适合。

下面来说一说具体的题目:

Hihocoder1174Hihocoder1174:模板题、

Hihocoder1175Hihocoder1175:在拓扑排序时,顺便递推一下,也比较简单。

UVAUVA 437437:这一题是要先构造出图来,然后DAG图上dp。主要难点在于想出构造图。当时刚刚看到这道题时,还是有点懵逼的。这类不好直接处理关系的题,可以考虑预处理一下关系,通过转化到图上(或其他类型的结构),再进行处理。

HDU4857HDU4857:这题挺坑的,输出要求是保证顺序条件的同时,依次保证11223.....3.....在前,而不是字典序的大小。最开始处理的时候,总是不自觉的处理成字典序了。但是字典序的处理提供了一个想法,字典序的处理是尽量保证小的在前,而如果要是11223.....3.....在前,即保证大的尽量在后面,这也就是反向构图,保证大的尽量在前面,然后再倒序输出。

Codeforces770CCodeforces 770C:这题的难度不大,可以考虑先反向构图,从每个被选中点去遍历,找出一个DAG图。然后在DAG图上拓扑排序得到答案。坑点在于判断无解的情况,最开始无解的情况在vis=1vis=1时,继续进行了dfsdfs,导致degdeg出了问题,最后使整个过程都出了点问题。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!