图论
1.分类
2.判断
若它的邻接矩阵(**就是个表格**)
以左对角线为轴,上下部分对称,则这个是无向图的邻接矩阵(因为如果a可以到b,那b也可到a)
像这个
a b距离默认为1,自己到自己为0
3.储存
领接矩阵
邻接表(**更高效**)· next 一般用-1(**方便调试**)
vector
前向星
树
树的储存
父亲节点表示法 用father[x]表示节点的父亲,第一个(**father[1] = -1**)
儿子节点表示法(不推荐,容易被菊花图坑)
无向图表示(上面)
左儿子右兄弟 – 树转二叉树· (最多只有二叉的数)
在左边的第一个作为儿子,放在左边,与其同一层为其兄弟,放在右边
原图操作后的
4.图的遍历
4.1 BFS
由一个点向四周放射状发出,这就是bfs搜索的一种形式。(提示,bfs在图论一般只适用于相邻两点之间距离为1的图。)
(queue [int] q;queue很慢,一般自己写数组)
之后补充
5.最短路
传递闭包:点击打开链接
松弛操作
原理:first 发现1-》3为13,second 发现1 -》2为1,2 - 》3为9,则1 -》2 -》3比1 -》3这个目前“最短路径”更短
代码实现
if (dis[u] + graph[u][v] < dis[v])
dis[v] = dis[u] + graph[u][v];
图的最短路算法-Floyd
原理 当a到b的距离为dis1,b到c的距离为dis2,则至少存在路径使a到c的距离为dis1+dis2。
适用范围
图的最短路算法 | Floyd | SPFA | Dijkstra |
原理 | 当a到b的距离为dis1,b到c的距离为dis2,则至少存在路径使a到c的距离为dis1+dis2。 | 一个基于贪心思想的一个单源最短路算法 | |
适用范围 | Floyd 算法是解决任意两点间的最短路径的一种算法,可以正确处理有向图或无向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包。 | 能处理负权边的单源最短路算法,但不能解决含有负权环的问题 | 不能解决含有负权边的题 |
图的最短路算法-Floyd
原理 当a到b的距离为dis1,b到c的距离为dis2,则至少存在路径使a到c的距离为dis1+dis2。
适用范围
Floyd 算法是解决任意两点间的最短路径的一种算法,可以正确处理有向图或无向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包。
Floyd算法使用的思想是:
1.枚举中转节点。
2.检查由S点经过此点到T点的路径是否比原先优。
3.更新由S点到T点的最短距离。
赋值
在oi中,由于正无穷在代码里难以表示,我们常将oo或inf定义为足够大的数字(0x3f3f3f3f等)来表示正无穷。(不用0xfffffff(-1)因为int里面第一个是符号位,3f是一个字节,可以用memset赋值;不用27383647因为如果两个正无穷相加会变为一个负值)
代码实现
单源最短路算法——Dij
原理 一个基于贪心思想的一个单源最短路算法
*单源:一个起点
*多源:多个起点
用邻接表储存
特点
1.每个点只访问一次(vis从0变为1)
玄学算法--SPFA
复杂度O(玄学),最坏N^2。常被出题人卡掉。(一般来说SPFA与dij会卡掉一个,另一个能通过)
具体是这个点击打开链接
大体原理:利用队列,如果到一个点的长度未改变,那么接下来暂时不用考虑这个点到其它的点的距离(出队),如果在之后的操作中到这个点的长度改变,那么这个点到其它点的距离会变,所以再把它入队 ,重复进行,最终知道a到f的最短路
循环列表
代码实现:
#define MAXN 10000
int q[MAXN],head;
//一般有这样的操作:
q[head] head++;
// or
q[haed++]
q[head] head++;
变为
q[(head) % MAXN] head++;
这样head在超出范围时又回到了开始,成为一个循环
(queue [int] q;queue很慢,一般自己写数组)