领接表和邻接矩阵的选择;
在我们做到有关图一类的问题时,当需要将一个图的内容存储下来的话一般有两种选择,一种是领接表【一般用(静态)链表来实现】,或者是领接矩形。
而选择时,一般将图分为两种图,这三种种图分别对应两种不同的存储图的方式;
楼主知识比较浅薄,整合知识有不够详细的还请见谅,欢迎大家来补充或者修改
各位小伙伴们大家好,在这里给大家拜年啦
这里提一下邻接矩阵和邻接表的区别;
邻接矩阵
邻接矩阵在使用时要将所有点初始化,将非自环(自己指向自己的边)初始化为正无穷,自环初始化为0即可这里是为了方便操作
邻接矩阵是将矩阵的纵坐标对应每一个点,比如x = 1 时对应的是点 n = 1;
而 矩阵中 如果 [x][y] = 1的话 ,就表示点 x可以通向 y的边, 同理 [y][x] = 1表示点 y 有通向 x的 边; 值得注意的是,矩阵中的横坐标严格对应起始点,纵坐标严格对应结束点 ,这样当要保存的边是有向边(只能从x点到y点) 这样就只需要将邻接矩阵中的 [x][y] = 1即可, 这里的 1 可以表示为边权(边权就是这一条边的值) .
同理如果要存储无向边(这条路线既可以从x到y也可以从y到x)就需要 将[x][y] = 1 , [y][x] = 1 ,就是存储两条边;
就好像这个图一样 这个图就是用邻接矩阵来存储的,注意这是一个无向图
可以看到每一条边对应的[x][y] 与[y][x]的值都是1 ;
而 当x == y 时矩阵的边是零,就是表明该点到自己的距离是0
邻接矩阵的优点是存图时操作方便,缺点是他特别的占空间
邻接表
领接表是将一个点可以指向的点存起来 ,可以用vector来存也或者可以用单单链表来存储,这里就直接用vector来存储了(个人习惯用链表来存)
比如说上方这个图
vector<int> a[6];
a[1] = {2,3,5};
a[2] = {1,4};
a[3] = {1,5};
a[4] = {2};
a[5] = {1,3};
这样就可以将这个图保存下来了,好处是操作容易,不用初始化,坏处是写起来会比较麻烦注意这里是无相图,相当于存储了两条方向相反但位置相同的边
接下里我们来区分使用的时候
第一类 即数据量极小
比如 n为 图中点的个数 ,m为图中边的个数,如果 n 和m 都是小于 50(这里50指的是小数据)的话,无论你选择邻接表还是邻接矩阵的话都是可以解决问题的 就好像是图的遍历类型的dfs 或者bfs都是可以随意选着图的存储方式(记得选自己熟练的嘿嘿)
第二类 边的数据范围远远超过点的数据范围
比如 n 为图中点的个数 , m为图中边的数量,一般当 m的数据范围>=n*n的时候我们认为这种图称为疏密图 , 因为边的数量大于 n的平方,所以很可能会存在两个点会有重复的边,但边权(这里可以理解为路费)可能不一样,这时候我们可以用邻接矩阵来存储这个图,并且在存储图的过程中只保留路费的最小值,这样就可以很好的解决重边的问题;
像这种图就只能用邻接矩阵来存储了
存储时可以这样存 , 这里省去了初始化;
cin >> n >> m ;
while(m--)
{
int a, b,c;
cin >> a >> b >>c;
g[a][b] = min(g[a][b],c);
}
第三类,点的数量远远超过边的数量
老样子,我们将 n表示点的数量,m表示边的数量。 当 n的数据范围 >= m*m的数据范围时 我们将这种图称为稀疏图,这种图如果用邻接矩阵来存的话,所用的空间很可能会直接爆栈(一种内存太大而使程序直接终止的说法),所以这种时候就可以用邻接表来存储了
比方说这个数据
这个数据当中如果直接用邻接表的话会很难受
所以这里我们用领接表来存储数据
这里我用单链表来存储图
int h[N] , ne[N] , e[N] ,w[N] ,idx;
int n , m;
int dist[N] , cnt[N];
bool st[N];
void insert(int a , int b , int c)
{
e[idx] = b;
w[idx] = c;
ne[idx] = h[a];
h[a] = idx ++ ;
}
int main()
{
cin >>n >> m ;
memset(h,-1,sizeof h);
while(m--)
{
int a ,b ,c;
scanf(" %d%d%d",&a,&b,&c);
insert(a,b,c);
}
这里用到的是单链表来存储数据,链表的插入用的是头查法,h可以看做是不存值的头结点,e是每一个节点的值,ne是当前结点指向的下一个结点的值,
idx在存储数据时当做指针使用;
具体的可以参考静态数组的实现;
最后祝大家 新的一年里 皮肤越来越好, 智商越来越来越高, 成绩越来越好, rank分越来越高,运气爆棚 ,一夜暴富,声名鹊起,一飞冲天 O(∩_∩)O哈哈~