6、图

1、概念

  • 顶点

  • 简单图:没有指向自己的边、没有重复的边

  • 无向图

    • 无向边(边)

    • :边/2

    • 连通:两顶点间有路径存在

    • 连通图:任意两个顶点都是联通的

      • 连通图最少边:n-1

      • 非连通图最多边:Cn12C_{n-1}^{2}

    • 连通分量:极大连通子图(包含尽可能多的子图和边)

    • 完全图::任意两个顶点之间都存在边

  • 有向图

    • 有向边(弧)

    • 入度、出度:有向图的度=入度+出度

    • 强连通:两个顶点之间正向、逆向均有路径

    • 强连通图:任意两个顶点之间都是强连通的

      • 强连通的最少边:n(环)

    • 连通分量:极大强连通子图(必须强连通、包括尽可能多的边和点)

    • 完全图:任意两个顶点之间都存在方向相反的两条弧

  • 简单图:没有指向自己的边、没有重复的边

  • 路径:两个顶点之间的顶点序列

  • 回路:第一个顶点和最后一个顶点相同的路径

  • 简单路径:路径中所有的顶点不重复出现

  • 简单回路:除了第一个和最后一个顶点外,其它顶点不重复

  • 路径长度:路径上的数量

  • 顶点到顶点的距离:最短路径(若存在)

  • 子图:首先是个图。分别取点集和边集的子集构成

  • 生成子图:子图中包含了原图的所有顶点

  • 生成树:包含全部顶点的一个极小连通子图(边尽可能少、保持联通)

  • 生成森林:由非连通图各个连通分量的生成树构成

  • 带权图

    • 边的权:边所带的权值

    • 带权路径长度:路径上所有边的权值之和

  • :不存在回路且连通的无向图

2、表示

邻接矩阵

有向图:

  • 出度:行

  • 入度:列

  • 优点

    • 快速查找两点之间是否有边

  • 缺点

    • 不适用于查找从某点出发的所有边

邻接表法

邻接表
  • 十字链表:有向图

  • 邻接多重表:无向图

  • 优点

    • 快速查找从某点出发的所有边

  • 缺点

    • 不适用于查找某两点之间是否有边

3、遍历

广度优先BFS

  • 节点入队

  • 队列非空,则将队头出队

  • 访问队头节点的相邻节点,并将之存入队尾

  • 循环操作直至队空

BFS函数调用的次数=连通分量数

时间复杂度

  • 邻接矩阵表示:

    • 访问所有顶点:O(V)

    • 访问每个顶点的邻接点:O(V)

    • 总时间复杂度:O(V2)O(V^2)

  • 邻接表表示:

    • 访问所有顶点:O(V)

    • 访问各个顶点的邻接点:O(E)

    • 总时间复杂度:O(V+E)O(V+E)

深度优先DFS

DFS调用的次数=顶点数

时间复杂度

  • 邻接矩阵表示:

    • 访问所有顶点:O(V)

    • 访问每个顶点的邻接点:O(V)

    • 总时间复杂度:O(V2)O(V^2)

  • 邻接表表示:

    • 访问所有顶点:O(V)

    • 访问各个顶点的邻接点:O(E)

    • 总时间复杂度:O(V+E)O(V+E)

4、最小生成树

  • Prim算法

    • 每次将代价最小的顶点接入树

    • 适合边稠密的图

    • 时间复杂度为:O(V2)O(|V^2|)

  • Kruskal算法

    • 每次选择权值最小的边,连接这条边的两个节点(两顶点不能都在已有集合中)

    • 适合边稀疏的图

    • 采用堆存放边的集合

    • 时间复杂度

      • 每次选择最小权值的边:O(logE)O(\log |E|)

      • 总时间复杂度:O(ElogE)O(|E|\log |E|)

5、最短路径

Dijkstra算法

  • 从某点除法,遍历所有未确定最短路径的点,算出其距离

  • 选择未确定的点中距离最短的作为下一个遍历的目标,并将其路径设为true

  • 将距离改为从新的点出发的路径中最短的

  • 不适合求有负权值的图

dijkstra1
dijkstra2
dijkstra2
dijkstra2
dijkstra2

Floyd算法

  • 首先不允许任何定点作为中转

  • 接下来允许在V0V_0中转

    • 对比原来A(1)A^{(-1)}矩阵中A(1)[i][k]A^{(-1)}[i][k]A(1)[i][j]+A(1)[j][k]A^{(-1)}[i][j]+A^{(-1)}[j][k]

    • 若中转路径大 ,则替换为新的,并修改path(0)[i][k]=0path^{(0)}[i][k]=0

    • 例:A(1)[2][1]>A(1)[1][0]+A(1)[0][2]=11A^{(-1)}[2][1]>A^{(-1)}[1][0] + A^{(-1)}[0][2]=11

  • 允许在V0V_0V1V_1中转

  • 允许在V0V_0V1V_1V2V_2中转

  • 查询最短路径

    • A(2)[1][2]=4A^{(2)}[1][2]=4path(2)[1][2]=1\text{path}^{(2)}[1][2]=-1

      • V1V_1V2V_2的最短路径为4

      • 不经过中转

    • A(2)[0][2]=10A^{(2)}[0][2]=10path(2)[0][2]=1\text{path}^{(2)}[0][2]=1

      • V0V_0V2V_2的最短路径为10

      • 经过V1V_1中转

  • 时间复杂度O(V3)O(|V|^3)

  • 空间复杂度O(V2)O(|V|^2)两个矩阵

实例

V0V_0V4V_4的最短路径

  1. 中转点为3

  2. V0V_0V3V_3中转点为2

  3. V0V_0V2V_2直接相连

  4. 目前路径为V0V2V3V4V_0 - V_2 - V_3 - V_4

  5. V2V_2V3V_3中转点为1

  6. 最短路径为V0V2V1V3V4V_0 - V_2 - V_1 - V_3 - V_4,为4

6、拓扑排序

DAG图:有向无环图

AOV网:使用DAG图表示一个工程,顶点表示活动

拓扑排序:找到做事的先后顺序

  • 从AOV网中找一个入度为0的顶点并输出

  • 从AOV网中删除这个顶点和所有以它为起点的边

  • 重复直到AOV网为空或者不存在入度为0的点为止

7、关键路径

AOE网:带权有向图,用边表示活动,边的权值表示活动的开销

关键路径:具有最大路径长度的路径,决定整个事件的完成时间

最早开始时间:弧起点所表示的事件最早开始的时间

最迟开始时间:弧尾所表示的事件最晚开始的时间

时间余量:不影响整个工程的情况下,事件可以拖延的时间

关键活动:时间余量为0的活动

最后更新于

这有帮助吗?