邻接矩阵
逻辑结构分为两部分:V和E集合,其中,V是顶点,E是边。因此,用一个一维数组存放图中所有顶点数据;用一个二维数组存放顶点间关系(边或弧)的数据,这个二维数组称为邻接矩阵。邻接矩阵又分为有向图邻接矩阵和无向图邻接矩阵
————百度百科
定义
- 对于无向图,邻接矩阵是对称的,对角线为 0
- 无向图中,任一顶点 i 的度为第 i 列(或第 i 行)所有非零元素的个数,在有向图中顶点 i 的出度为第 i 行所有非零元素的个数,而入度为第 i 列所有非零元素的个数
- 存图空间为 (n^2) , 由于无向图对称且对称轴为 0,仅需 (n(n-1)/2)
特点
容易判断两个点是否相连,方便求度,但对于一个稀疏图,空间上会浪费很多,所以要注意数据范围
int n, m, o[zx][zx];
cin >> n >> m;
for(int i = 1; i <= m; i++){
cin >> u >> v;
o[u][v] = 1;
// o[v][u] = 1; 无向图,也可以比较一下u v的大小只存一个三角形的图
}
不知道为什么看到网上的大佬们写30多行的指针 就很迷,心慌慌
邻接表
直接举栗子 o( =∩ω∩= )
4 5 //4个点 5条边
1 4 9 //点 点 边权
4 3 8
1 2 5
2 4 6
1 3 7
上面右图为链表表示的邻接表,是不是看到指针很激动, 下面介绍一下不用指针的邻接表
使用数组实现,每个点都存从这个点出发的所有边,,此时要给每条边编号,如下图
这里用三个数组记录(u,v,w)
再用一个数组first存每个顶点其中一条边的编号(为了方便枚举每个顶点所连的边),例如1 4 9,表示为first[1] = 1; 若一个点 i 出度为 0,则令first[i] = -1; 在读入前,先给first数组初始化为 1;
1 4 9 是以1为起点扫到的第一条边,next数组赋值为 -1 , 4 3 8 同理
现在读入1 2 5, 把 first[1] 更新为 3,让 next[3] 存原来 first[1] 的值,这样就能连起来了
不难发现,遍历顶点1的所有边就跳来跳去就行了
建表
int n, m, u[zx], v[zx], w[zx], fisrt[zx], next[zx];
cin >> n >> m;
for(int i = 1; i <= n; i++) first[1] = -1;
for(int i = 1; i <= m; i++){
cin >> u[i] >> v[i] >> w[i];
next[i] = first[u[i]];
first[u[i]] = i;
}
遍历其中一个点 i
int k = first[i];
while(k != -1){
k = next[k];
.....
}
遍历全部
for(int i = 1; i <= n; i++){
int k = first[i];
while(k != -1){
k = next[k];
.....
}
}
啊,一个建图也没啥好讲的,**毕竟都是大佬 **
✿✿ヽ(°▽°)ノ❀