对于无向图,只要进行DFS(v)如果出现之前访问过的点u就说明有回边,可以将dfs过程中的点输入到一个hash中,检查hash是否有冲突来看是否访问过那个点。DFS就是回溯的过程,递归调用邻接表的指针即可,DFS会遍历图中所有的点,从而形成一棵生成树。BFS则是用一个优先队列来做,算法上表现为分支限界。但是对于有向图而言,如果进行DFS(v)如果出现之前访问过的点u却不能说明有回边,因为可以有这样的情况
有向图 u->p->v->w->h
对应无向图 u-p-v-w-h 则v的深度优先遍历为 v-w-h(回溯)->p->u
即dfs的起始点v是有前驱的,因此会有两课生成树v->w->h和u->p,形成生成森林
,如果在dfs(v)结束前生成树上出现 v->****->u->v->****则说明有环
基本数学概念:
等价关系: 如果集合上的关系是 自反的,对称的(a~b=>b~a)和传递的,则称
为R是集合上的偏序关系。
偏序关系: 如果集合上的关系是 自反的(a<=a),反对称的(若a<=b&&b<=a则
a=b)和传递的(a<=b&b<=c则a<=c),则称为R是集合上的偏序关系,pair(集
合,<=)的集合称为posets即偏序集)。
全序关系: 如果集合中的每个元素都可以比较,则称为全序关系(偏序为
partial order,即存在两个元素不可比的情况即a!<=b&&b!<=a)
偏序集合中的全序集合称为偏序集合的一个chain,即该chain即拓扑排序.
用图中两个元素之间是否有有向的边来表示是否两个元素存在偏序关系。
对于DAG,若两个元素之间没有边,则可以人为地加一个边,认为两个元素之间
有偏序(从而整个集合可以比较从而有全序关系即拓扑排序),但是对于有环的图
,环上的两个节点是无法确定谁优先的,因此无法进行拓扑排序。
拓扑排序认为加不存在的边后是否会形成环呢?显然可以形成环,这样的例子太好举了,这里人为加边的意思是当图中存在多个没有前驱的节点时,则这些节点自然没有偏序关系,无法比较,在拓扑排序的过程中认为地选择一个没有前驱的节点输出,这就是人为加边的意思。
偏序模型的实际场景:
在学习自控前必须学习高数,课程之间的优先关系可以表示为一种偏序,两种课
程无关则表示无法比较。偏序也可以表示为一种流程图(施工流程图,产品生产
流程,或者程序数据流图---非DAG的数据流图则表示有死循环).
偏序的图模型:AOV activity on vertex: 顶点表示活动,边表示活动间的优先
次序,即偏序关系。
AOV应该是DAG,如何判断是DAG呢?即进行拓扑排序,形成一个chain,则学生若
每学期只能上一门课则应该按照这个顺序来修。
原因在于若存在环,则环上的两个节点是无法比较的,即没有偏序关系。
拓扑排序(AOV这个DAG->CHAIN)的方法:
(1)在DG中选择一个没有前驱的节点并输出(没有前驱表明其最优先)
(2)从图中删除该顶点和所有以它为尾(源头)的弧{即从该点出发的弧}
重复以上两个步骤,得到
若
1.全部顶点输出,则说明该DG为DAG
2.若剩下的节点,则说明在这些节点中不存在没有前驱的顶点(所有剩下的点都
有前驱,即存在环路,所有节点都可以通过其他节点到达,否则一条直线总会有
一个头吧)