当前位置:文档之家› 信息学奥林匹克竞赛培训资料 图论基础

信息学奥林匹克竞赛培训资料 图论基础

信息学奥林匹克竞赛培训资料图论基础图论基础
一、3种数据模型
线性表(数组、链表):1:1
树(普通树、二叉树、森林):1:n,线性链表可以看成是树的特例(单链)
,树也可以看成是图的特例图(无向图、有向图):m:n
二、图的基本概念
1、图=(顶点集,边集),顶点集必须非空,关键是把什么抽象成顶点,什么抽象成边,
2、图的分类:无向图和有向图,区分在于边是否可逆,
3、加权图(又称网或网络):权的含义,不加权的图也可以认为权是1。

4、阶和度:一个图的阶是指图中顶点的个数。

如果顶点A、B之间有一条边相连,则称顶点A和B是关联的;
顶点的度是指与该顶点相关联的边的数目,奇点和偶点,
对于有向图存在入度与出度之分;
定理:无向图中所有顶点的度之和等于边数的2倍;
有向图中所有顶点的入度之和等于所有顶点的出度之和;
任意一个无向图一定有偶数个(或0个)奇点; 5、完全图:一个n阶的完全无向图含有n*(n-1)/2条边;
一个n阶的完全有向图含有n*(n-1)条边;
稠密图:当一个图的边数接近完全图时;
稀疏图:当一个图的边数远远少于完全图时;
在具体使用时,要选用不同的存储结构;
6、子图:从一个图中取出若干顶点、若干边构成的一个新的图;
7、路径:对于图G=(V,E),对于顶点a,b,如果存在一些顶点序列
x=a,x,……,x=b(k>1),且12k(x,x)?E,i=1,2…k-1,则称顶点序列x,x,……,x为顶点
a到顶点b的一条路径,而路径ii+112k
上边的数目(即k-1)称为该路径的长度。

并称顶点集合{x,x,……,x}为一个连通
集。

12k8、简单路径:如果一条路径上的顶点除了起点和终点可以相同外,其它顶
点均不相同,则称此路径为一条简单路径;起点和终点相同的简单路径称为回路(或环)。

下左图1—2—3是一条简单路径,长度为2,而1—3—4—1—3就不是简单路
径;下右图1-2-1
为一个回路。

9、有根图:在一个图中,如果从顶点U到顶点V有路径,则称U和V是连通的;
在一个图中,若存在一个顶点W,它与其它顶点都是连通的,则称此图为有根
图,顶点W即为它的根,下面的两个图都是有根图,左图的1、2、3、4都可以作
为根;而右图的1、2才可以作为根。

10、连通图:如果一个无向图中,任意两个顶点之间都是连通的,则称该无向
图为连通图。

否则称为非连通图;上左图为一个连通图。

强连通图:在一个有向图中,对于任意两个顶点U和V,都存在着一条从U到V
的有向路径,同时也存在着一条从V到U的有向路径,则称该有向图为强连通图;
上右图不是一个强连通图。

连通分支:一个无向图的连通分支定义为该图的最大连通子图,左图的连通分
支是它本身。

强连通分支:一个有向图的强连通分支定义为该图的最大的强连通子图,右图含有两个强连通分支,一个是1和2构成的一个子图,一个是3独立构成的一个子图。

三、图的存储结构(n阶e条边)
存储邻接表表示法方比法邻接矩阵表示法边集数组表示法 (链式存储法) 较
直观方便,很容易查找存储稀疏图时,空间效便于查找任一顶点的关联边及图中任两个顶点i和j率比较好,也比较直观关联点,只要从表头向量中取之间有无边(或弧),出对应的表头指针,然后进行优点以及边上的权值,只要查找即可。

查找运算的时间复
看A[i,j]的值即可,时杂性平均为O(e/n)
间复杂性为O(1)
存储稀疏图,则会造成不适合对顶点的运算要查找一个顶点的前驱顶点和
很大的空间浪费和对任意一条边的运以此顶点为终点的边、以及该
算顶点的入度就不方便了,需要缺点扫描整个表,时间复杂度为O
(n+e)。

可以用十字邻接表改

计算一个顶点的度(或从空间复杂性上讲,边对任一顶点的关联边(顶点)
入度、出度)和关联点,集数组适合于存储稀进行不断、重复的运算适用场合其时间复杂性均为O疏图和那些对边依次
(n) 进行处理的运算
空间复杂度 O(n*n) O(3e) ? O(6e+2n)
四、图的遍历
1、概念
从图中某一顶点出发系统地访问图中所有顶点,使每个顶点恰好被访问一次,这种运算操作被称为图的遍历。

为了避免重复访问某个顶点,可以设一个标志数组visited[i],未访问时值为false,访问一次后就改为true。

图的遍历分为深度优先遍历和广度(宽度)优先遍历两种方法。

2、深度优先遍历
图的深度优先搜索类似于树的先序遍历。

从图中某个顶点V出发,访问此顶点并作已访问标i
记,然后从V的一个未被访问过的邻接点V出发再进行深度优先遍历,当V的所有邻接点都被访iji问过时,则退回到上一个顶点V,再从V的另一个未被访问过的邻接点出发进行深度优先遍历,kk
直至图中所有顶点都被访问到为止。

如下左图从顶点a出发,进行深度优先遍历的结果为:a,b,c,d,e,g,f;右图从V出发进行深度优先遍历的结果为:V,V,V,V,V,V,V,V。

112485367
对于一个连通图,深度优先遍历的递归过程如下。

图用邻接表存储} Procedure dfs(i:integer); {
Begin
访问顶点i;
Visited[i]:=True;p:=g[i].link;
While p<>Nil Do {按深度优先搜索的顺序遍历与i相关联的所有顶点}
Begin
j:=p^.adj; {j为i的一个后继}
If Not Visited[j] Then dfs(j); {递归}
p:=p^.next; {p为i的下一个后继}
End;
End;
Procedure dfs(i:integer); {图用邻接矩阵存储}
Begin
访问顶点i;
Visited[i]:=True;
For j:=1 to n do {按深度优先搜索的顺序遍历与i相关联的所有顶点}
Begin
If (Not Visited[j]) and (a[i,j]=1) Then dfs(j);
End;
End;
以上dfs(i)的时间复杂度为O(n*n)。

对于一个非连通图,调用一次本过程
dfs(i),即按深度优先顺序依次访问了顶点i所在的(强)连通分支。

主程序如下: procedure work;{邻接矩阵}
begin
fillchar(Visited,sizeof(Visited),0); {初始化}
for i:=1 to n do {深度优先搜索每一个为访问的顶点}
if not Visited then dfs(i);
end;
3、广度(宽度)优先遍历
图的广度优先搜索类似于树的按层次遍历。

从图中某个顶点V出发,访问此顶点,然后依次0
访问与V邻接的、未被访问过的所有顶点,然后再分别从这些顶点出发进行广度优先遍历,直到0
图中所有被访问过的顶点的相邻顶点都被访问到。

若此时图中还有顶点尚未被访问,则另选图中一个未被访问过的顶点作为起点,重复上述过程,直到图中所有顶点都被访问到为止。

如上左图从顶点a出发,进行广度优先遍历的结果为:a,b,d,e,f,c,g;如上右图从顶点V出发,进1行广度优先遍历的结果为:V,V,V,V,V,V,V,V。

12345678
两种遍历方法相比,深度优先遍历实际上是尽可能地走“顶点表”;而广度优先遍历是尽可能沿顶点的“边表”进行访问,然后再沿边表对应顶点的边表进行访问,因此,有关边表的顶点需要保存(用队列,先进先出),以便进一步进行广度优先遍历。

下面是广度优先遍历的过程: Procedure bfs(i:integer); {图用邻接矩阵表示}
Begin
访问顶点i;
Visited[i]:=true;
顶点i入队q;
while 队列q非空 do
begin
v; 从队列q中取出队首元素
for j:=1 to n do
begin
if (ot Visited[j]) and (a[v,j]=1) then
begin
访问顶点j;
Visited[j]:=true;
顶点j入队q
end;
end;
end;
End;
以上bfs(i)的时间复杂度仍为O(n*n)。

对于一个非连通图,调用一次本过程bfs(i),即按广度优先顺序依次访问了顶点i所在的(强)连通分支。

主程序如下: procedure work;{邻接矩阵}
begin
fillchar(Visited,sizeof(Visited),0);
for i:=1 to n do {广度优先搜索每一个为访问的顶点}
if not Visited then bfs(i);
end;。

相关主题