最近新学的东西太多实在有点吃不下来,先静下来回顾一下最重要的搜索:BFS和DFS,它们是图论中搜索的核心内容。
-----------------------------------------手动分割-----------------------------------------
下面以有向简单图的BFS、DFS为例,假设每个顶点只经过一次,要求DFS先序遍历每个顶点并输出,BFS遍历每个顶点(要求同一广度顶点从小到大排列)并输出:
1.存储、构建有向简单图:
方法:vector和vector嵌套(相当于二维数组但空间复杂度为O(m),暂时只考虑边不考虑存储顶点),v[i][k]表示(i,k)有向边,遍历所有边存储即可。
2.假设是深度优先搜索:
核心:递归的调用,是否回溯?在哪一步递归?递归前后怎么调整?
- 经过每个顶点之前需要判断该顶点是否已经被输出/遍历过,用visited[顶点数]来当作标记数组。
- 先输出进入递归函数的顶点,然后对以该顶点为起点形成的有向边进行遍历,在循环体内添加判断语句:若没有被经过过,那么让该条边被指向的顶点进入dfs递归。
深度优先搜索(寻找所有可能解)的操作模板(熟记于心):
void
3.假设是宽度优先搜索:
核心:利用队列储存顶点,不断地删除队首添加队尾元素。
- 利用队列,先预处理让vector行下标最小的顶点入队。
- 队首出队,一个循环体让队首代表的顶点指向的所有顶点入队,其中一个添加判断,若没有被访问过,让该顶点入队尾,然后标记该顶点被访问过。
- 宽度的模板较简单就不列出了,需要注意的是有的并不只向两个方向广度搜索而是朝四个方向搜索,那么最好用一个flag二维数组储存上下左右的矢量,然后再循环的时候对上一个数对加减这个就可以了。
待续。
图的常见储存结构:
- 有向无环图,边无权:01邻接矩阵表示,若无向则把每条边看成双向的,且邻接矩阵为对称矩阵。一般用二维数组存储邻接矩阵/向量二维组,表示从行到列的有向边。
- 无向无环图,边有权:边权为元素的邻接对称矩阵表示,未连接的顶点则以INF表示。一般用二维数组存储邻接矩阵/向量二维组。
- 一般在搜索的时候循环体内需要实现判断两顶点形成相应的邻接矩阵元素是否为0.
待续。
一些常见的:
1.总之是能够提速的操作,写在main函数里开头就可以
ios
2.数字的快读快输:
int
3.优先队列关于结构体的cmp函数:
struct cmp {
bool operator()(struct name q,struct name p){
return q.? < p.?;
}
}
4.方便自己debug:
#ifdef _DEBUG
freopen("input.txt" , "r" , stdin);
freopen("output.txt" , "w" , stdout);
#endif
待续。