【学术篇】浅谈各种邻接表
来源:互联网 发布:windows私有云软件 编辑:程序博客网 时间:2024/06/05 23:55
首先注:下面出现的代码完全没经编译,不保证编译成功,大家当伪代码看较好~
在OIer的世界里,有一种奇妙的东西,叫图论。。
而对于计算机,我们并不能将一张图输入,而需要一些存图方式
比如下面这张图(画得不好看勿喷~):
最简单的存图方式是邻接矩阵
*在一个n*n的矩阵中,第(i,j)个格子的值表示从i到j这条边的边权。。
上图用邻接矩阵表示就是:
图的储存结构:
int tu[N][N];
建边:
inline void build(int x,int y,int z){ //建从x到y边权为z的边 tu[x][y]=z; //单向边#ifdef DOUBLE_EDGE tu[y][x]=z; //双向边#endif}
枚举边:
int x=start;for(int i=0;i<n;i++) if(tu[x][i]){ //若不为0表示相连 int y=i; //跑到i的点 }
这个东西有个显而易见的缺点,O(n^2)的效率就决定了无法处理任何大规模的数据。。
而O(nlogn)的算法中的n基本都在10^5级别。。数组都开不开啊_ (:з」∠) _
所以我们需要邻接表,这样时间、空间效率都被控制在O(m)级别(m为边数)
正统的邻接表是用指针……
邻接表对于每个点主要保存了以下东西:
- 这个点出发的第一条边
- 每条边(和下面的都指该点出发的边)所指向的点
- 每条边的边权(data域)
- 每条边指向的下一条边
储存的结构基本上是这样的:
struct edge{ int to,data; etype *next,*pair; //pair为反向边,视情况而建 edge(){} edge(int t,int d,edge* nxt):to(t),data(d),next(nxt){} //dalao们发现C++的new实在是太慢了,所以要自己写一个orz void* operator new(unsigned,void* p){return p;}}*e[N];/*还有一个*/int Pe=0; //记录了边的总数
建边:
void build(int x,int y,int z){ e[x]=new(Pe++)edge(y,z,e[x]); //指向y,边权z,上一条边是上一个e[x]..#ifdef DOUBLE_EDGE e[y]=new(Pe++)edge(x,z,e[y]); e[x]->pair=e[y]; e[y]->pair=e[x];#endif}
枚举边:
int x=start;for(etype *i=e[no];i;i=i->next) int y=i->to;
嗯,很好,我们现在有了存图的利器
但是,指针的特性决定了对我们精确的要求。。 不禁想起了指针调试的恐惧
所以,我们应该是有更简(ju)便(ruo)的方法的:
比如,数组模拟……(这应该也是应用最广泛的吧……)
于是存储结构变成了:
struct edge{ int to,next,data;}e[M]; int v[N],tot=0; //v数组就是很多很多dalao的first数组,存点i出发的第一条边备查//网络流图中tot为了异或找反向边容易可以置为1..
建边:
void build(int x,int y,int z){ e[++tot].to=y; e[tot].next=v[x]; e[tot].data=z; v[x]=tot;#ifdef DOUBLE_EDGE e[++tot].to=x; e[tot].next=v[y]; e[tot].data=z; v[y]=tot;#endif}
枚举边:
int x=start;for(int i=v[x];i;i=e[i].edge) int y=e[i].to;
对就是这样。。
其实似乎写到这里就可以结束了。。
但是其实还是有一种写法的。。
比如,C++的盆友们,还记得你们的STL么?
vector也可以用来存邻接表哦(下面我给出没有边权的)~ (而且似乎省选开O2什么的STL会格外跑得快)
存储结构?
vector<int> e[N];
建边:
void build(int x,int y){ e[x].push_back(y); //媲美邻接矩阵的简便..#ifdef DOUBLE_EDGE e[y].push_back(x);#endif}
枚举边:
int x=start;for(/*unsigned*/int i=0;i<e[x].size();i++){ //不想要warning的可以加unsigned.. int y=e[x][i];}
行了,就介绍这么多。。。
希望对大家有帮助,希望大家用的开心~~
- 【学术篇】浅谈各种邻接表
- 十字链表 邻接表实现各种操作
- 数据结构C语言版之邻接表(各种遍历)
- 基于邻接表的图的各种遍历
- 邻接表
- 邻接表
- 邻接表
- 邻接表
- 邻接表
- 邻接表
- 邻接表
- 邻接表
- 邻接表
- 邻接表
- 邻接表
- 邻接表
- 邻接表
- 邻接表
- 分布式服务框架学习笔记8 ActiveMQ入门使用
- Samba 软连接文件无法访问,拒绝访问。【已解决】
- Google搜索
- IntelliJ IDEA 2016.3.5 基础配置及部分问题(持续更新中...)
- NetRipper源码のDLL
- 【学术篇】浅谈各种邻接表
- CSS:清除浮动
- Redis特性一览
- 数据结构----归并排序(转载)
- Zybo板运行Linux系统原理总结
- 洛谷P2480 [SDOI2010]古代猪文
- Mesos超配:让集群利用率可以达到100%
- 在Spring MVC中,事务可以加在Controller层
- Storm运行原理探索