1、图的相关知识点
注意:只总结自己不会的
(1)关联矩阵
关联矩阵即用一个矩阵来表示各个点和每条边之间的关系。
对于左图为一个无向图G,右图为其关联矩阵。对于关联矩阵第一行1 1 1 0,表示点v1和各边的关系。如图1所示,v1和e1,e2,e3相连,和e4未连,故关联矩阵的值为1 1 1 0. 下面各行为点v2,v3, v4和各边的关联,以此类推。
(2)邻接表
邻接表是图的一种最主要存储结构,用来描述图上的每一个点。对图的每个顶点建立一个容器(n个顶点建立n个容器),第i个容器中的结点包含顶点Vi的所有邻接顶点。实际上我们常用的邻接矩阵就是一种未离散化每个点的边集的邻接表。
(3)正向表
它的特点是将每个顶点的邻接顶点集中在一起存放。
有向图的正向表使用一个一维|V|元数组A和一个一维|E|元数组B表示,
无向图的正向表使用一个一维|V|元数组A和一个一维2|E|元数组B表示。
具体做法:
-
首先将所有邻接于顶点1的顶点标号依次写入B中,并将最后一个邻接顶点在B的地址记录在A[1]中;
-
然后将所有邻接于顶点2的顶点标号依次写入B中,并将最后一个邻接顶点在B中的地址记录在A[2]中;
-
这样一直进行下去,直到与最后一个顶点相邻的顶点标号都存入B为止。
正向表的空间代价与邻接表相当,但是由于正向表没有使用指针而减少了一部分结构性开销。
更容易理解版:
注此处的数组下标从1开始,而非从0开始
有向图:对邻接矩阵的行进行压缩,将所有节点的直接后继依次存放在一起(依次指的是先存放1号节点的后继,在存放2号节点的后继,以此类推,直到n号节点的后继),构成数组B[m],但是只凭借B[m]我们只知道每条边的后继,不知道前驱,因此再构建数组A[n],A[i]表示节点i的第一个直接后继在B[m]中出现的位置。比如A={1,2,5,5,8},B={2,2,3,4,3,1,1},A[2]=2,A[3]=5,因此B[2],B[3],B[4]都是2号节点的后继,代表的边依次为(2,2)(2,3)(2,4)。此外,还可以添加叔祖Z[m],表示每条边的权重。
无向图:无向图的正向表需要将B的长度由m扩充为2m,原因如下:若1,2节点之间存在一条边,那么第一次需要添加(1,2),第二次需要添加(2,1),故每条边需要添加两次。
参考:离散数学(2)第一章 基本概念_在一个无向图g中,次为奇数的点,是奇数个,还是偶数个?-CSDN博客
(4)逆向表
思路与正向表相同,只不过B[m]中存放的是每条边的直接前驱。比如A=[1,3,5,7,8],B=[4,4,1,2,2,4,2],A[2]=3,A[3]=5,那么夹在B[3]和B[5]之间(左闭右开)的就是2号点的直接前驱,边为(1,2)(2,2)
2、题目
(1)描述
给定一张 n 个点 m 条边的图,有可能存在重边和自环。请你给出这张图所有的代数表示。
(2)输入格式
第一行四个正整数 n,m,type1 和 type2。其中 n 和 m 分别表示图的点数和边数。type1=0 表示该图为无向图,type1=1 表示该图为有向图。type2=0 表示该图不是赋权图,type2=1 表示该图是赋权图。
如果 type2=0,接下来 m 行,每行两个正整数 u 和 v 表示一条边。
如果 type2=1,接下来 m 行,每行三个正整数 u , v 和 d 表示一条边,其中 d 为这条边的边权。
(4)输出格式
按顺序输出下列代数表示:
-
邻接矩阵或权矩阵。输出 n 行,每行 n 个数表示矩阵。如果该图存在重边则不输出。如果 type2=0 输出邻接矩阵,如果 type2=1 输出权矩阵。
-
关联矩阵。输出 n 行,每行 m 个数表示矩阵。如果 type2=1 或有自环则不输出。
-
邻接表。输出 n 行。如果 type2=0 每行输出 di 个数,其中 di 为节点 i 的度数(无向图)或正度(有向图),每个数表示一条与 i 相接的边。如果 type2=1 每行输出 di 个数,每两个数表示一条边。
-
正向表。如果 type2=0 输出两行,分别表示向量 A 和向量 B 。如果type2=1 输出三行,分别表示向量 A,向量 B 和向量 Z。
-
逆向表。如果 type1=0 则不输出(因为此时逆向表与正向表相同)。如果 type2=0 输出两行,分别表示向量 A 和向量 B 。如果 type2=1 输出三行,分别表示向量 A,向量 B 和向量 Z。
其中,邻接表、正向表、逆向表每个点对应的所有边按输入顺序输出。
正向表与逆向表的 A向量是 n+1 维向量,有向图中 A(n+1)=m+1,无向图中 A(n+1)=2m+1。
(4)理解思路
注意:数组下标从0开始,图顶点下标从1开始
根据输入内容考虑:
非赋权图:使用二维数组yuan一一对应其顶点(m行2列)
赋权图:使用二维数组yuan一一对应其顶点(m行3列)
根据输出内容考虑:
1.邻接矩阵/权矩阵
首先用二维数组a(n行n列)表示该矩阵,初始化数字为0,无权图有边为1,有权图有边为权值。无向图赋值权值两次(一次性),有向图即赋值一次
存在重边:
无向图:根据输入的数组,若赋值时已不是0,则存在重边,所以不输出,计算出来方便后续使用。<