开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
前向星的名字很好听,但它并不是一颗真正星星呀。 它是一种很特别的边集数组,数组里面的边,以起点为下标,按照序号升序来排序。同起点的边,按照终点升序排序。
构建前向星我们需要两个数据结构
边数组
这个我们构建一个结构体
struct edge{
int to,dis,last;
}e[2333];
对于每条边有三个属性
-
to: 边的终点 -
last: 边的起点连接的上一条边 -
dis:边的长度
PS:我们讲过,边集合数组里面的边是按照起点从小到大排序的,而且一个起点可能连接着许多条边,所以一条边的 last属性就是 起点连接的上一条终点序号更小的边
由上图我们知道,一号点连接着三个终点,那么就产生了三条边。这些边的起点都是一号点,因此他们按照终点升序来排序。另外,每条边的 last属性讲的是该点连接的上一条终点序号更小的边,倘若该边就是起点连接的第一条边,那么这条边的 last 可以设为-1或者0.(边序号默认从1开始)
| 边序号 | 起点序号 | 终点序号 | 起点的上一条边序号 |
|---|---|---|---|
| 1 | 1 | 2 | 0 |
| 2 | 1 | 3 | 1 |
| 3 | 1 | 4 | 2 |
我们通过上面的表格可以发现:起点1的上一条边序号会随着我们边的增加进行更新 0==>1==>2 。当边3创建完毕后,我们点1的最后一条出边就是边3了
上面我们讲了同一个起点的边集合情况,接下来我们讲不同起点应该怎么办。
我们引入第二个数据结构
next数组
其实这个数组存的就是 每个点连接的最后一条出边的序号
它以 点的序号为下标,该点连接的最后一条边序号为值。
每当一个点连接某个点,产生新边后,这个点的next数组就更新为新边的序号
由上图我们知道, 点1的最后连接的出边为边3, 点2的最后连接的出边为边5, 点3的最后连接的出边为边6 点4的最后连接的出边为边8, 点5,6,7均无出边。 因此我们可以把上面图的next数组作出:
| next[1] | 3 |
|---|---|
| next[2] | 5 |
| next[3] | 6 |
| next[4] | 8 |
| next[5] | 0 |
| next[6] | 0 |
| next[7] | 0 |
接下来我们按照链式前向⭐来构建这张图
图中带黑框的数字是边的长度
🆗 我们再来回顾下 ,我们构建前向星用了两个结构。
第一个
第二个
然后我们构建前向星的边还会用到一个加边函数add , 这个就是我们构建前向星的本质
Add函数
void add(int u,int v,int d){
e[++cnt].to=v;
e[cnt].d=d;
e[cnt].last=next[u];
next[u]=cnt;
}
在上面这个函数中,cnt变量指的就是边的序号,它从1开始 ,每构建一条新边,cnt就增加1.
我们的next数组的存的是该点连接的最后一条出边的序号,因此每当某个点构建一条新边时,我们要更新它的next存的值。至于我们这条边的last属性,自然就是在构建这条边之前,尚未更新的next数组啦。
建图
现在我们给出的数据形式是这样的:
第一行给出两个整数n m
接下来m行,每行给出三个整数 u ,v,d 分别代表一条边的起点 ,终点,长度
数据如下:
5 8
1 2 3
1 3 4
2 3 1
2 4 6
3 4 7
3 5 10
4 3 2
4 5 5
我们现在按顺序来构建每一条边
| 边序号 | 起点 | 终点 | 长度 | e[]数组属性 | next[]更新 |
|---|---|---|---|---|---|
| <1> | 1 | 2 | 3 | e[1]:to=2,d=3;last=0 | next[1]:0=>1 |
| <2> | 1 | 3 | 4 | e[2]:to=3,d=4;last=1 | next[1]:1=>2 |
| <3> | 2 | 3 | 1 | e[3]:to=3,d=1;last=0 | next[2]:0=>3 |
| <4> | 2 | 4 | 6 | e[4]:to=4,d=6;last=3 | next[2]:3=>4 |
| <5> | 3 | 4 | 7 | e[5]:to=4,d=7;last=0 | next[3]:0=>5 |
| <6> | 3 | 5 | 10 | e[6]:to=3,d=10;last=5 | next[1]:5=>6 |
| <7> | 4 | 3 | 2 | e[7]:to=3,d=2;last=0 | next[1]:0=>7 |
| <8> | 4 | 5 | 5 | e[8]:to=5,d=5;last=4 | next[1]:4=>8 |