目录
写在前面
2020华为软件精英挑战赛京津冀东北赛区“花样划水”队,初赛第4,复赛第2,决赛第23。 本来因为决赛成绩不理想,就不打算开源了,如今比赛已经过去将近一个月,最近有人跟我说想看看当时比赛的代码,找代码的时候发现对代码已经没啥印象了。 于是决定趁着对代码还有点印象,做一个整理并开源,算是对我的第一次比赛经历做一个总结和复盘,同时也算是一个留念,因为代码仅用于比赛,且当时时间有限,所以并未过多考虑可读性和编程规范。一个月后自己重新看了下代码感觉像一坨屎。比赛结束后我也没有再继续修改了,就保持了当时提交的原样开源了。
初赛
初赛的大致规则是:给定一组转账(即给定一个有向图),找出所有节点数小于8,大于2的环并输出,输出的环要求按照字典序最小的节点位于第一个位置,并以每个环的第一个节点的字典序对环进行排序。
初赛的时间周期比较长,我报名的时候比赛已经进行到一半了,所幸最后还来得及。
第一代思路
第一代的思路是先将图做预处理,对节点进行升序排序,并对每个节点的出边做升序排序。然后将每个点作为源点进行搜索(字典序小的先搜索,字典序大的后搜索),搜索过程中只访问大于源点id的节点,这样做的目的是既避免了重复输出环,又使得输出天然按照题目所要求的顺序。具体的搜索方法为沿着源点的反向展开3层,记录访问的点以及路径,再正向做深度为4的深度优先遍历,当访问到记录过的节点时进行输出。然而遗憾的是,这个方法虽然在思路上简单,但实现起来极复杂,并且我在实现的时候使用了不少unordered_map,因此最终速度极慢,但思路中还是有可取之处,我最终采取的反向标记三层的方法也算是脱胎于这个方法。
第二代思路
第二代的思路是找到所有环并把节点数小于8,大于2的环输出。于是通过stackoverflow上的Finding all cycles in a directed graph提问,找到了这篇1975年DONALD B. JOHNSON的有向图找环的论文