图的学习 - luogu - Course - OI - 数据结构
什么是图
图是描述物件之间的关系。
物件就是结点,物件之间的关系即是边。
所以我们可以发现几乎所有的关系都可以表示成图,dp可以表示成DAG(有向无环图),搜索本质上是图的遍历算法,树也是特殊的图……
且图的存在也是非常重要的,很多问题都需要图的解决,比如导航就可以用图实现。
图的储存方式
图有多种储存方式,比如邻接矩阵,比如用vector。
邻接矩阵
定义 $map[u][v]$ (map是c++关键字)表示u和v节点直接有一条边。
空间复杂度为$O(n^{2})$,在$n<=10^3$的时候适用。
举个例子,现在输入2个人,他们是朋友,最后统计每个人有多少个朋友。
我们可以定义$w[1e3+5$][1e3+5]来存储2个人是否为朋友,遍历$w[i][1~n]$即可判断是否为朋友。
这样我们就用实现了$O(n)$输入,$O(n)$查询。
1 |
|
vector存图
vector存图可能是用的最多的了,有的人喜欢用链式前向星来存图,但实际上vector就是在做链式前向星做的事。
对于每一个点,开一个vector存下他的边,空间复杂度:$O(m)$,查询时间复杂度:$O(m)$是不是比邻接矩阵好多了?
当然当节点较少时还是邻接矩阵方便。
再将刚刚的问题用vector表示一下:
1 |
|
总结
邻接矩阵:用$w[u][v]$存边权即可。
vector:需要写个结构体,来把邻居编号和边权打包起来;
邻接矩阵和vector存图的选择
图分为稀疏图和稠密图,当节点非常多,而边非常少的时候,他为稀疏图,反之则为稠密图。
因为vector没东西的时候几乎不用空间,所以我们可以选择vector,而当节点非常少,边非常多的时候我们就可以选择邻接矩阵存图。
有向图
刚刚我们为什么要把u和v都存一下对方呢?因为刚刚我们存储的是无向图,即两边都通,所以我们就需要把u和v都存一条通向对方的边。
有向图只需要只存一条边即可。
This post was written on Aug 16, 2022.