1.图的基本概念和存储方式

本篇仅简单叙述自己对图的理解,大概是随笔性质,本人水平有限,难免有不足之处,请见谅!

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最钟爱的存图方式!

额,下篇更新最短路!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容