图论学习报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
图论学习报告
报告内容:
一.基本概念:
1.叙述图:所谓图G是一个三元组,记做G=
≠∅,称为图G的结点集合;E(G)=(e1,e2,…,en),是G的边的集合。ψ(G)称为关联函数。
2.有向图:每一条边都是有向边的图称为有向图。
3.无向图:每一条边都是无向边的图称为有向图。
4.欧拉图:含欧拉回路的无向连通图与含有有向欧拉回路的弱连通有向图统称为欧拉图。
5.哈密顿图:具有哈密顿回路的无向图,与具有哈密顿有向回路的有向图统称为哈密顿图。
6.最短路径:在加权图中找出二个指定点之间的最短路叫做最短路径。
7.树:无圈连通无向图叫做树。
8.二叉树:每个节点最多只有二个子树的树叫做二叉树。
9.最小支撑树:连通加权图里权和最小的支撑树称为最小支撑树。
10.最优二叉树:在所有的带权w1,w2,w3,…,wt的二叉树中,带权最小的二叉树称为最优二
叉树。
11.平面图:如果图G能够示画在曲面S上,且使得它的边近在断点处相交,则称G可嵌入
曲面S。如果图G可以嵌入平面上,则称G是可平面图,已经嵌入平面上的图g称为G 的平面表示。G与g都简称为平面图。
二.算法设计
1:写出Dijkstra算法
{G带有顶点a=v0,v1,…,vn=z和权w(vi,vj),若{vi,vj}不是G中的边,则w(vi,vj)=∞} For i:=1 to n
L(vi): ∞
L(a):=0
S:= ¢
{初始化标记,a的标记为0,其余结点标记为∞,S是空集}
While z∉S
Begin
u:=不属于S的L(u)最小的一个顶点
S:=S∪{u}
For所有不属于S的顶点v
If L(u)+w(u,v) Then L(v):=L(u)+w(u,v) {这样就给S中添加带最小标记点并且更新不在S中的顶点的标记} End{L(z)=从a到z的最短路长度} 2:写出Floyd算法 把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则G[i,j]=d,d表示该路的长度;否则G [i,j]=空值。 定义一个矩阵D用来记录所插入点的信息,D[i,j]表示从Vi到Vj需要经过的点,初始化D[i,j]=j。 把各个顶点插入图中,比较插点后的距离与原来的距离,G[i,j] = min( G[i,j], G[i,k]+G[k,j] ),如果G[i,j]的值变小,则D[i,j]=k。 在G中包含有两点之间最短道路的信息,而在D中则包含了最短通路径的信息。 比如,要寻找从V5到V1的路径。根据D,假如D(5,1)=3则说明从V5到V1经过V3,路径为{V5,V3,V1},如果D(5,3)=3,说明V5与V3直接相连,如果D(3,1)=1,说明V3与V1直接相连。 3:写出求最小支撑树的算法 普林算法: (G:带n个顶点的连通无向图) T:=权最小的边 For i:=1 to n-2 Begin e :=与T里顶点相关联的权最小的边,并且若添加到T里则不形成圈 T:=添加e之后的T End{T是G的最小支撑树} 普林算法的另一种形式 (G:加权连通图) For j :=1 to n do begin Lj :=w(s,j){临时标号} B(j):=s; End Ls :=0 设置Ls为固定的 While 遗留临时标号do Begin 选择最小临时标号Li 设置Li为固定的 边{i,B(i)}加入T 结点i加入T for每个临时标号Lk do If w(i,k)<Lk then Begin Lk:=w(i,k) B(k):=i End End Return End{T为G的最小支撑树} 克鲁斯卡尔算法 (G:n个顶点的连通加权无向图) T:=空图 For i:=1 to n-1 Begin e :=当添加到T里时不形成圈的G里权最小的边 T:=添加e之后的T End{T是G的最小支撑树} 三:程序实现 1:写出Warshall算法的C语言程序 #include #include Void mian() { Int A[10][10]; Int n,I,j,k; Printf(“输入关系矩阵的维数n(n<10)\n”); Scanf(“%d”,&n); Printf(“输入n*n个数据(0 or 1)\n”); For(i=1;i<=n;i++) { For(j=1;j<=n;j++) { Scanf(“%d”,&A[i][j]); If(A[i][j]!=1&&A[i][j]) Printf(“there is a error”); } } For(i=1;i<=n;i++) { For(j=1;j<=n;j++) { For(k=1;k<=n;k++) { If(A[i][j]&&(A[i][k]||A[j][k])) A[i][k]=1; } } } Printf(“传递闭包的关系矩阵:\n”); For(i=1;i<=n;i++) { For(j=1;j<=n;j++) Printf(“%2d”,A[i][j]); Printf(“\n”);