一般来说,我们会用三种存图方式,分别是邻接矩阵、邻接表、vector模仿邻接表。
邻接矩阵
就是开一个二维数组Map[i][j]表示从i到j的距离;可以清楚地表示出点与点之间的关系;
用Floyd、Prime处理问题时,通常就用这种方式来存图。
邻接表
我们用三个数组来分别存储出点与边、边与同出点的边、边与到达顶点的关系、边权,分别是:head[maxnode]、ne[maxedge]、to[maxedge]、w[maxedge];
其中head[i]表示由i引出的边中你输入的最后一条的edgenum为head[i],需要在最开始时赋初值为0或-1;
ne[i]表示i这条边的前一条和i的出发点相同的边的edgenum为ne[i];
to[i]表示i这条边所能到达的节点的编号为to[i];
这种方法便于我们寻找两点是否有边相连,比用邻接矩阵则是O(n)的时间快了很多。通常用与遍历图、Dijkstra、SPFA等算法。
对于新增加的边
void addedge(int f,int t,int co) { ne[++edgenum]=head[f]; head[f]=edgenum; to[edgenum]=t; w[edgenum]=co; }
这种算法利用的原理是链表,当然这四个数组中的ne、to、w可以用一个结构体合在一起。
在用这种方式时对于边的遍历方式如下:
//head赋初值为-1 //u表示出发点,v表示到达点 for(int i=head[u];i!=-1;i=ne[i]) { int v=to[i]; }
Vecotor存图
我们可以用一个动态数组来保存图;
vector<int> G[maxnode]; //加入一条从u到i的边 G[u].push_back(v); //遍历从u出发的所有边 for(int i=0;i<G[u].size();i++) { int v=G[u][i]; ``````
对于这种方法,要比邻接表跑起来慢一些,但是,这种方法写起来就是要简单一些。如果要保存权值,则可以用结构体来保存。