题目大意:好像就是先告诉你他要用26个字母的前n个字母,然后给你m条对这n个字母的限制,每一条限制这n个字母其中的两个的先后关系,问你通过这些限制条件能不能确定这n的字母的序列。注意:当存在冲突或者拓扑排序成功时,之后的输入不对结果造成影响。(一开始因为这个一直在wa)
思路:A<B即可以理解成存在边A-B。n个点组成的图,给你m条边。问你该图是否为DAG(无有向环图)然后是否拓扑序唯一,最后求拓扑序。关于Kahn算法:找出所有入度为0的点,这些点都存入结果数组中(这些点拍成任意顺序都可以,因为不会有其他点必须在它左边)然后枚举这些点(任意顺序),依次判断这个点的所有出边(判断之前在图中删除该边),如果出边的另一端的点,当前入度(删除边之后)为0,就可以把他放入结果数组之中(他已经保证了在以它为终点的所有的起点的右边,以后再往数组里放的点,都能在它右边),如果不是,就不入数组,但是删的边也不要还原(因为现在也已经保证了,该边的起点在终点左边)。 网上查到了对这个算法更简单的描述:取出图中所有入度为0的点,然后删除这些点(包括其出边),再一次取出所有入度为0的点。知道所有点都被取出。
对于这道题所要求的拓扑排序唯一,在Kahn算法实现过程中,不能有这么随意,也就是说,一开始,入度为0的点只能有一个,然后每次对结果数组中的点,判断其所有出边的另一端是否可以进入数组的时候,有且只有一个点可以进去。然后下一次判断出边的点,也是唯一确定的了。如果某一次,进入的点不止一个或者没有点入队,那么,不能确定该拓扑序(在判断完该图为DAG的前提下)。 在网上查得另一种保证拓扑排序唯一的方法,对排序完成的数组中,每两个相邻的点进行一次判断,判断其之间是否有从左顶点指向右顶点的有向边,如果没有,那么我把这两个点调换位置,一定可以得到另一个不同的拓扑序列。
然而还有一个问题就是:必须写出,一条一条读入之后,读入了第几条边的时候,该拓扑序确定。 我可以加一条边判断一次吗,虽然感觉很麻烦,但是它就是很麻烦啊^_^#,而且low,而且low,而且low。他并没有给出m的大小,其实仔细想一下复杂度,如果给的这m条都是不重复的,那最多也就是26*25条,Kahn的话,复杂度我感觉应该就是26个点,每个点25条出边,也是25*26。乘在一起,一个测试实例复杂度大概就是422500,乍一看也不高啊。另一个问题是怎么判断该无权有向图,不存在有向环。即为DAG图。注意也许该图根本不连通。
注:不能用Bellman-Ford判断一个图是否存在正权环回路。
整整做了一整天,还是没做出来。把所有后台测试数据都找出来,就是有一组不对。明天改。还是代码实现的问题,dfs、bfs要重新练。
新闻热点
疑难解答