存图的几种方法

  图论中存图是不可避免的,下面来总结一下几种存图的方法

  1,邻接矩阵存图,假如有n个点,那就开一个n*n的数组f,f[i][j]的权值代表i到j的边长,初始化为正无穷或者负无穷或者0代表两个点之间没有边。

  2,动态数组存图,开一个动态数组,把每一个与i相连的点都放到a[i]后边,需要用的时候拿出来用,这时候如果还有边权的话就需要开两个vector,两个同步,一个存终点,另一个存边权。

  3,也是我今天想说的终点,链式前向星存图,这是应用最广泛的存图方法,借助结构体来完成,这个结构体是存的边的信息,一般不需要存起点,需要存的变量有终点,边权和这条边的上一条边。存出来的边都是有向边,所以对于无向边需要正反存两边,终点就是这条边指向哪里,边权就是边长,而这条边的上一条边是指上一条和这条边同一起点的边,举个例子对于起点7,他的出边有1,3,9,10,下一次第12条边也是以7位起点,那么12的上一条边就是10,这样是为了保证通过最后一条边就把起点的所有出边都找到。虽然起点不需要存,但我们需要开一个数组head,head[i]存储的是第i个点的最后一条边是谁,这样当我们需要从一个点出发的时候就通过head找到这个点的最后一个出边,通过这条边不断的往前找从而找到前面的所有边。

void add(int x,int y)
 {
     tot++,tu[tot].last=head[x],head[x]=tot,tu[tot].to=y;
 }

这就是加边操作,x是起点,y是终点,tot是当前一共加了多少条边,head数组不用初始化,默认值为0,所以遍历一个点的出边时的操作如下:

for(int i=head[x];i;i=tu[i].last)

当找到了一条边,它的上一条边编号为0,那么他就是这个点的出边里最开始的那一条了,由于是从后往前找,所以找到第一条也就全部找完了。

如果有边权的话,可以把边权传过去,在add函数里多一步记边权即可。

由于这是有向边,存成无向边需要存两次,所以需要把tu这个数据结构开成边的两倍大小。

原文地址:https://www.cnblogs.com/yuelian/p/11213922.html