刷题(11)-图(3)

图的表示: 稀疏图 邻接表
           稠密图 邻接矩阵
深搜 DFS
实现:递归
      非递归
应用:
            连通分量
广搜 BFS
实现: 队列

无向图
表示:邻接表/邻接矩阵

可达性: DFS (BFS也可)

单点最短路径:BFS

连通分量: DFS (BFS  并查集)

有向图:
表示:邻接表/邻接矩阵

可达性: DFS (BFS也可)

单点最短有向路径:BFS

检查有无环:DFS

拓扑排序:
    定义:
        对所有顶点排序 使得任意有向边都是从排在前边的顶点指向排在后面的元素
    解决方法:
        1. 入度为0的入队方法  c++数据结构 p320
        2. DFS的逆后序   递归之后压入栈 
    必须是无环图 才有拓扑排序

有向无环图 把所有顶点排序,保证所有的有向边都是排在前面的顶点指向后面的顶点

1)用队列实现,入度为0的顶点入队, 然后进行循环,条件队列不为空,第一个元素出队,同时设为已访问且放进一个数组A里面,对这个元素的所有领接点入度减1,假如入度为0 了,就入队,

退出循环之后,遍历所有点,看有没有没访问的,有就是有环,也就没有拓扑排序,没有那就输出数组A,就是拓扑排序

2)用DFS的逆后序,这个方法首先需要检查有没有环

检查的方法是,加一个bool数组,数组的size为节点个数的Onstack,还有个int * cycle 放找到的第一个有向环 ,然后对所有的节点,没有被mark的v,挨个做DFS,具体是,把这个onstack[v]和mark[v]设为true,然后遍历它的邻接点w,假如有cycle不等于nullptr,也就是已经找到环了,直接return,假如没有,再检查有没有被mark过else if,没有就edge[w] = v,再递归做dfs,  再检查w有没有在栈里面 else if (onstack[w] )  在就是找到环了(因为意味着前面存在w到v,然后现在v到w,所以是个环),然后从v开始 沿着edgeto 直到w 放进cycle,最后再放v。

最后把onstack[v] 重新变回false

检查如果没环,这时候再用dfs,这时候,每个递归完之后,把这个v压入栈里面,最后把栈弹光就是图的拓扑排序、
    tips:
        (有向无环图才有拓扑排序)

强连通分量: 
    定义:
        分量中任意两个顶点都是强连通分量(存在a->b, 也存在b->a,这叫做强连通分量)
    解决方法:
         kosaraju算法:有向图找强连通分量

        1) G^R(反向图) 求拓扑排序

        2)按上面的排序 对G 进行DFS
kosaraju(实际用了两次DFS)

加权无向图:
(一般求最小生成树)
表示:邻接表  但链表节点是edge

prim算法和kruskal算法

最小生成树
只有连通图(从图的任意一个顶点能到任意另一个顶点)才存在最小生成树

生成树是图的一颗含有其所有顶点的无环连通子图,最小生成树,就是权值和最小的生成树
子图(图 边的一个子集(以及边上的那些顶点))
我们讨论的最小生成树是在一副加权连通无向图中的,(权值相不相同,无所谓,权值是正是负也无所谓)

两个算法不能处理有向图,所以一般最小生成树都是针对加权无向图而言的都基于两个基础

1)图的任意切分,横切边权重最小者必定属于最小生成树

2)贪心算法:命题k p392  每次找到一种切分,它的横切边 均不为黑色(黑色代表MST的一个边),把最小权值的横切边涂成黑色,重复,直到有 顶点数-1个边为止(最小生成树的边数量一定是顶点数-1)

kruskal算法:

基本思路,把所有边由小到大排序,每次取最小的边,假如不会和已经在MST中的边形成一个环,那就加进来,下一个,假如会形成环,抛弃,下一个。循环直到有 v-1个边

具体方法:最小堆把边排序,并查集识别会形成环的边,队列保存MST结果

时空复杂度:v个顶点,E条边

空间: E

时间: ElogE (最坏)

prim算法:
从节点0开始 每次把   有且只有一个节点在MST里面的边,且这个边是符合条件的最小权值,这个边加到MST里面,直到有V-1个边

lazy实现   时空复杂度:v个顶点,E条边  空间: E   时间: ElogE (最坏)

eager实现: 空间:v  时间ElogE(最坏)

加权有向图(一般目的就是求最小路径树)
表示:邻接表,链表节点是有向edge

权重非负:Dijkstra算法 (将distTo[] 最小的非树顶点放松,并加入树中)

无环(权值可以负):按拓扑顺序 放松顶点

一般情况(权值可以负,可以有环,但别有负权重环,存在负权重环,最短路径树就不存在了):Bellman-Ford算法

https://blog.csdn.net/a60782885/article/details/72781811

最小生成树
只有连通图(从图的任意一个顶点能到任意另一个顶点)才存在最小生成树

生成树是图的一颗含有其所有顶点的无环连通子图,最小生成树,就是权值和最小的生成树
子图(图 边的一个子集(以及边上的那些顶点))
我们讨论的最小生成树是在一副加权连通无向图中的,(权值相不相同,无所谓,权值是正是负也无所谓)

两个算法不能处理有向图,所以一般最小生成树都是针对加权无向图而言的都基于两个基础

1)图的任意切分,横切边权重最小者必定属于最小生成树

2)贪心算法:命题k p392  每次找到一种切分,它的横切边 均不为黑色(黑色代表MST的一个边),把最小权值的横切边涂成黑色,重复,直到有 顶点数-1个边为止(最小生成树的边数量一定是顶点数-1)

kruskal算法:

基本思路,把所有边由小到大排序,每次取最小的边,假如不会和已经在MST中的边形成一个环,那就加进来,下一个,假如会形成环,抛弃,下一个。循环直到有 v-1个边

具体方法:最小堆把边排序,并查集识别会形成环的边,队列保存MST结果

时空复杂度:v个顶点,E条边

空间: E

时间: ElogE (最坏)

prim算法:
从节点0开始 每次把   有且只有一个节点在MST里面的边,且这个边是符合条件的最小权值,这个边加到MST里面,直到有V-1个边

lazy实现   时空复杂度:v个顶点,E条边  空间: E   时间: ElogE (最坏)

eager实现: 空间:v  时间ElogE(最坏)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值