本篇仅简单叙述自己对图的理解,大概是随笔性质,本人水平有限,难免有不足之处,请见谅!
1.图,顾名思义,就是由一个个节点和边组成的一种结构。如下
点和边共同构成图,为了方便大家广义的理解,不讲定义,只简单的把边分为有向边和无向边,其实所谓无向边,不过就是两个起点终点相反的有向边而已,在我的理解里是没有无向边这个概念的
那么什么情况下需要建图,来个例子,比如啊,你现在要找人办事,但你确不认识别人,于是聪明的你想知道自己的朋友是否认识此人,亦或者自己朋友的朋友是否认识此人,这时候就可以建立一个图,人为节点,互相认识的人连边(这里为了方便假设互相认识啦,就是双向边哦),于是引入下一个概念,路径,如果你可以从自己找到一条路到办事的人,βヾ(,,・∇・,,川那么你就成功啦!(配合上面的图,实用更佳)
可是我们如何存储图,唔,是个难题,下面介绍三种常用的方法啦
以下均已n个节点,m条边举例
1邻接矩阵
顾名思义,是开一个n*n的矩阵,如果边上没有信息的话是可以开bool类型哦,有边权还是开个int吧
用第x行第y列的值来表示x->y是否有联系哈!当然,为了照顾对应的反向边,第y行第x列代表的就剩y->x边了,我想学过线代的人应该很容易就能明白吧,下面来个例子
如果自环的话,就是所谓自己连自己,对角线上的数字就也可以是1哦
2.邻接表
邻接矩阵固然方便,查询两个点之间的关系也很方便,但是n*n的空间实在是让人不敢恭维,尤其是有的图点很多但是边很少的时候简直让人炸裂,这该怎么办鸭QAQ,聪明的前人就创造了邻接表这种存图方式
邻接表啊,其实是开了n个链表,链表中的元素是自定义的结构,包括一个节点数据和指向下一个元素的指针,比如下图的v1,他的指针指向v2,v2的指针指向v3,v3的指针则为空,这样我们通过遍历链表,就可以得到以v1为起点的所有节点啦!是不是比邻接矩阵要省很多内存鸭
3链式前向星
如果你理解了邻接表,我想这个对你来说也是不难的!先膜拜一下大佬,据说这个东西是一位acmer发明的,也是目前我们打比赛最常用的存图方式啦,一定要好好掌握!以下代码无法跑通,仅做帮助大家理解所用,先对其中出现的一些数组进行解释,我自定义了一个结构体,其中有qian,wei,quan三个参数,一共共定义了201000个,这就是我们存边用的,一个元素代表了一条边,假设u是起点,v是终点,t是权值,wei就是此边指向的节点也就是v,quan则是权值t,qian不是此边的起点哦,这里则是代表存储的上一条以u为起点的边的编号,在朝下看,cnt就是边的编号,每建立一条边都要讲他++,这样就可以通过bian[cnt]来查询边的信息,head[i]则是以i为起点最后存贮的边的编号,比如一共有三条边以i为起点,他们的cnt编号分别是1 3 8,那么head[i]在更新完会变成8哦,这是由你加边顺序决定的,好,接下来看重头戏
add加边函数,传入u(起),v(终点),t(权值)三个参数;首先,cnt要++,这不难理解,因为这是一条新边,这条新边的尾和权直接进行赋值就可,关键来了!此时的head[u]正是添加此边之前以u为起点的最后一条边的编号,可是他马上就不再是最后一条了,他得退位让贤!可是他存贮的数据不能丢!怎么办!于是他被bian[cnt].qian接受了,他成为了新边之前以u为起点的最后被添加的边,head[u]顺势更新为cnt,毕竟新添加的这个边最新,而我们的head[u]存的是是以u为起点最后存贮的边的编号,如果有些混乱,不妨自己写一遍
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
struct xing
{
int qian,wei,quan;
}bian[201000];
int n,o1,o2,o3,m,head[11000]
void add(int u,int v,int t)
{
bian[++cnt].qian=head[u];
bian[cnt].wei=v;
bian[cnt].quan=t;
head[u]=cnt;
}
cin>>m;
for(int i=1;i<m;i++)
{
cin>>o1>>o2>>o3;
add(o1,o2,o3);
add(o2,o1,o3);
}
机智的同学一定发现了!这不就是邻接表吗!没错,这就是个邻接表,不过是个静态的,省去了指针窜来窜去的痛苦哦,下面贴一段找以u为起点的所有边的遍历代码
for(int i=head[u];i;i=bian[i].qian)
{
int v=bian[i].wei;
}
只要顺着qian所存贮的编号找直到没有,就可以遍历一遍这些边了,这也暴露了链式前向星的缺点,那就是无法通过编号快速得知起点是谁,但是他极其适合遍历,时间和空间复杂度也很优秀,还是成为了acmer最钟爱的存图方式!
额,下篇更新最短路!