链式前向星 && 手写Hash
链式前向星
对于图来说,链式前向星的概念就不得不提及了,其中的链表的思想也是手写Hash的重要一环
什么是链式前向星,就是利用链表的方式存图
定义一个结构体,其中包含next和to
next:表示与这个边起点相同的上一条边的编号
to:表示这条边的终点
ecnt:表示边的编号
还要定义一个head数组,head[i]表示以i为起点的最后一条边的编号
最开始head数组赋值为-1
加边操作
1 | void add(int from,int to){ |
通过加边操作我们可以记录所有从from出去的边,然后把每条边的前面的值放入next值中。
那么我们遍历每个点的边是,只要递归地寻找head[i],然后再往E[i].next找即可
1 | for(int i=0; i<n; i++){ |
完整代码
1 | const int maxn = 110; |
手写Hash
c++的STL有hash的两个函数,一个是map一个是unorder_map,都可以标记哪个数是否出现过,效率还可以$logn$,但是常数大。
我们可以直接手写Hash,利用链式前向星的思想,找一个不是特别大的质模数,然后对于每个模数相当于建立一个点,每次出现一个同模的就可以建立一条边,比如模数为$mod$,就会有$mod$个余数,每次加数的时候先求余数,然后加到那个余数集合里面,存储就用链式前向星的方法。
当数不是特别大特别多的时候,这个效率还可以。
但是这种一般题目可以用,(一般还是用unorder_map,这里只是介绍一种思想),如果卡模数就没办法了,只能更换模数。
1 | struct Hash{ |