目录
1 链式前向星概括
以同起点为一条链,数组head[a]存储起点a的最新录入的一条边的索引,每条边以结构体的形式存储该边信息(该边终点,权值,同起点的边中的上一条边即上一次录入的边的位置),所有边构成一个结构体数组。
很多帖子说到的是存储的是下一条边,这种理解很容易给人误导,应该是每一条边都能通过自身结构体存储的信息回溯到上一条边,所以叫前向星。
假如我们要找出一条a -> b的边,先根据head[a]找出从起点a出发的所有边里最新录入的那条边,然后根据该边找出它的上一条边,再根据上一条边找出它的上上一条边……直到找到一条终点为b的边为止。整个过程是链式回溯的,所以是链式前向星。
2 链式前向星范例
边的录入顺序(起点a -> 终点b = 权值w):
第0条边:5 -> 3 = 1 此时head[5]=0 以5为起点没有上一条边
第1条边:1 -> 2 = 9 此时head[1]=1 以1为起点没有上一条边
第2条边:3 -> 5 = 11 此时head[3]=2 以3为起点没有上一条边
第3条边:2 -> 1 = 5 此时head[2]=3 以2为起点没有上一条边
第4条边:4 -> 5 = 6 此时head[4]=4 以4为起点没有上一条边
第5条边:3 -> 1 = 7 此时head[3]=5 以3为起点的上一条边的是第2条边
第6条边:3 -> 4 = 4 此时head[3]=6 以3为起点的上一条边的是第5条边
第7条边:4 -> 1 = 2 此时head[4]=7 以4为起点的上一条边的是第4条边
假如我们要找3 -> 5这条边:
- 根据head[3]=6,得到起点3的最新一条录入的边是第6条边
- 根据edge[6].to=4,这条是3 -> 4的边,不符合,我们继续找
- 根据edge[6].pre=5,得到第6条边的上一条同起点边是第5条边
- 根据edge[5].to=1,这条是3 -> 1的边,不符合,我们继续找
- 根据edge[5].pre=2,得到第5条边的上一条同起点边是第2条边
- 根据edge[2].to=5,这条是3 -> 5的边,找到了
3 链式前向星实现
3.1 具体实现
边的结构体定义,存储该边信息
struct Edge{
int to;//表示该边的终点
int pre;//同起点的上一条边的位置,值为-1表示没有上一条边
int w;//该边权值
};
定义链头head,存储每个起点的最新一条边的索引,-1表示该点无边
int head[n+1];
memset(head,-1,sizeof(head));
定义结构体数组edge,存储每一次录入的边
Edge edge[2*m+2];
定义一个边的计数器ecnt,表示当前已录入边的数量
int ecnt=0;
增边函数,增加一条a -> b的权值为w的边
inline void addEdge(int a