链式前向星存图
链式前向星存图
首先我们要开四个数组,分别为$head[a],to[i],nxt[i],val[i]$,表示以$a$为起点的第一条边的编号,第$i$条边所指向的点,第$i$条边的下一条边的编号,第$i$条边的权值。
我们是链表将一条边储存在数组之中。加边的时候有四条语序:
void add(int a,int b,int c) //表示将一条从a指向b的权值为c的有向边添加到链表之中 { nxt[++idx]=head[a]; //idx为边的编号,++idx是将新边赋予编号,将新边的nxt指向原来head[a]指向的 //边的编号,这样能保证原来边的编号不失去。 to[idx]=b; //将新边的to赋值成为b,表示这条边指向b val[idx]=c; //将新边的val赋值成为c,表示这条边的边权为c head[a]=idx; //让head[a]指向当前边的编号,表示这条边是从a来的 }
我们应该怎么找到这些边呢?下面以找到$p$为开始点的所有边。
int main() { for(int i=head[p];i;i=nxt[i]) //我们可以通过head数组找到以p为开头的第一条边,并用nxt一直找下 //去,因为head数组最开始为0,所以当i等于0时,就是结束。 printf("%d %d %d ",p,to[i],val[i]); }
这是链式前向星存储图,因为这是有向边,所以存储无向边是只需要拆成两条相反的有向边就可以,注意数组要开二倍。
链式前向星和邻接矩阵的对比
在边数远远小于点数的平方时,一般运用链式前向星来储存边,这样可以大大减小空间,但是链式前向星不能在$O(1)$时间内找到任意一条边。