秋季集训第2周训练笔记

图的存储结构

1.二维数组邻接矩阵存储
邻接矩阵的参考程序段
#include<iostream> 
using namespace std; 
int i,j,k,e,n; 
double g[101][101]; 
double w; 
int main() 
{ 
 int i,j; 
 for (i = 1; i <= n; i++) 
  for (j = 1; j <= n; j++) 
   g[i][j] = 0x3f3f3f3f(赋一个超大值);  //初始化,对于不带权的图g[i][j]=0,表示没有边连通。这里用0x3f3f3f3f代替无穷大。 
   cin >> e; 
    for (k = 1; k <= e; k++) 
    { 
     cin >> i >> j >> w;           //读入两个顶点序号及权值 
     g[i][j] = w;                    //对于不带权的图
     g[i][j]=1 g[j][i] = w;          //无向图的对称性,如果是有向图则不要有这句! 
 } 
 ………… 
 return 0; 
} 

建立邻接矩阵时,有两个小技巧:

初始化数组大可不必使用两重for循环。

  1. 如果是int数组,采用memset(g, 0x7f, sizeof(g))可全部初始化为一个很大的数(略小于0x7fffffff),使用memset(g, 0, sizeof(g)),全部清为0,使用memset(g, 0xaf, sizeof(g)),全部初始化为一个很小的数。

  2. 如果是double数组,采用memset(g,127,sizeof(g));可全部初始化为一个很大的数1.38*10306,使用memset(g, 0, sizeof(g))全部清 为0.

2.数组模拟邻接表存储

图的邻接表存储法,又叫链式存储法。本来是要采用链表实现的,但大多数情况下 只要用数组模拟即可。

两种情况要具体而用

图的遍历

(一)深度优先与广度优先遍历

从图中某一顶点出发系统地访问图中所有顶点,使每个顶点恰好被访问一次,这种 运算操作被称为图的遍历。为了避免重复访问某个顶点,可以设一个标志数组visited[i], 未访问时值为false,访问一次后就改为true。 图的遍历分为深度优先遍历和广度优先遍历两种方法,两者的时间效率都是O(n*n)。

深度优先遍历

深度优先遍历与深搜DFS相似,从一个点A出发,将这个点标为已访问 visited[i]:=true;,然后再访问所有与之相连,且未被访问过的点。当A的所有邻接点都被 访问过后,再退回到A的上一个点(假设是B),再从B的另一个未被访问的邻接点出发, 继续遍历。

广度优先遍历

广度优先遍历并不常用,从编程复杂度的角度考虑,通常采用的是深度优先遍历。 广度优先遍历和广搜BFS相似,因此使用广度优先遍历一张图并不需要掌握什么新的 知识,在原有的广度优先搜索的基础上,做一点小小的修改,就成了广度优先遍历算法。

(二)一笔画问题

如果一个图存在一笔画,则一笔画的路径叫做欧拉路,如果最后又回到起点,那这 个路径叫做欧拉回路。 我们定义奇点是指跟这个点相连的边数目有奇数个的点。对于能够一笔画的图,我 们有以下两个定理。 定理1:存在欧拉路的条件:图是连通的,有且只有2个奇点。 定理2:存在欧拉回路的条件:图是连通的,有0个奇点。 两个定理的正确性是显而易见的,既然每条边都要经过一次,那么对于欧拉路,除 了起点和终点外,每个点如果进入了一次,显然一定要出去一次,显然是偶点。对于欧 拉回路,每个点进入和出去次数一定都是相等的,显然没有奇点。 求欧拉路的算法很简单,使用深度优先遍历即可。 根据一笔画的两个定理,如果寻找欧拉回路,对任意一个点执行深度优先遍历;找 欧拉路,则对一个奇点执行DFS,时间复杂度为O(m+n),m为边数,n是点数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值