数组模拟邻接表存图
数组模拟邻接表存图
邻接表的介绍
- 邻接表是一个链表
- 该链表的每一个节点都是一个单独的链表的head结点。
- 邻接表的主要作用/最常见作用是存图,相较于邻接矩阵有较低的时间复杂度。
因为本人是个蒟蒻,再加上用指针没人给你debug,所以就不放code了。
数组模拟邻接表
因为它的作用是存图,所以定义的变量名我就按存图代码来写了。
为了节约空间,降低空间复杂度,避免MLE,所以我选择用STL容器vector(对于每个测试点数组大小不同,不用new运算符是为了防止RE):
vector<int> head,edge,Next,weihght
,其中head[\(i\)]数组表示结点\(i\)的一条边,而这条边会通过节点编号(我用\(id\)来表示),访问Next数组的下标为\(id\)的元素,找到结点\(i\)的下一条边(而这一条边会通过同样的方式访问到再下一条边,直到访问完结点\(i\)的每一条边)。
数组weight,它的下标为\(id\)的元素表示的是边\(id\)的权值。
数组edge,它的下标为\(id\)的元素表示的是边\(id\)通向的点。
代码实现部分
初始化
为了方便构建一张图,一般在main函数的开头利用vector类的resize()成员函数给edge,Next,head,weight数组申请需要的空间。
特别地,对于head数组,其他数组的大小依边数而确定,而head数组的大小依点数而定。head数组中如果一个元素值为0,代表着编号为该元素的下标的点无以它为起点的边。
遍历代码(dfs)我就不写了,只提供增加边函数和main函数片段
#include<bits/stdc++.h>
using namespace std;
int id=0;//表示目前边数的值
vector<int> edge,Next,head,weight;
void add(int from,int to,int pay)//from为这条边的起点,to为终点,pay为权值
{
edge[++id] = to;//记录边的终点
weight[id] = pay;//记录权值
Next[id] = head[from];//插入结点,链表断开
head[from] = id;//重新链接链表,结点已插入
id++;//更新边数
}
int main()
{
int n,m;// n为点数,m为边数
cin >> n >> m;
head.resize(n+1);
edge.resize(m+1);
Next.resize(m+1);
weight.resize(m+1);
//略
}