链式前向星和邻接表一样,只是存储方式变成了数组!
head数组存储最后插入该链表的边的编号,每条边插入都是在该链表的表头插入,然后head前移指向当前新边(即当前编号tot),新节点指向原来的头结点!Next数组相当于邻接表的Next指针,存储指向同起点的另一条边的编号;edge数组存储当前边编号对应的边的终点!
注意:
next
不能使用,会和系统变量冲突,,使用Next
或ne
- 无向图需要存储两次,反向正向都是路径
- 有向图只需要存储一次
tot
从0和1开始都可以,他只是影响边的编号,我们不在意,边的编号一般是1开始!
// 5 7
// 1 2 1
// 2 3 2
// 3 4 3
// 1 3 4
// 4 1 5
// 1 5 6
// 4 5 7
// 1
// Next[i]:以i为起点的下一条边的终点
// head[i]:以i为起点的最后一条边的编号
// 对于1 2 1这条边:edge[0] = 2; Next[0] = -1; head[1] = 0;
// 对于2 3 2这条边:edge[1] = 3; Next[1] = -1; head[2] = 1;
// 对于3 4 3这条边:edge[2] = 4; Next[2] = -1; head[3] = 2;
// 对于1 3 4这条边:edge[3] = 3; Next[3] = 0; head[1] = 3;
// 对于4 1 5这条边:edge[4] = 1; Next[4] = -1; head[4] = 4;
// 对于1 5 6这条边:edge[5] = 5; Next[5] = 3; head[1] = 5;
// 对于4 5 7这条边:edge[6] = 5; Next[6] = 4; head[4] = 6;
// 看i = 1的情况,head[1] = 5, edge[5] = 5 1 -> 5
// Next[5] = 3, edge[3] = 3 1 -> 3
// Next[3] = 0, edge[0] = 2 1 -> 2
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e5 + 10;
int head[N], edge[N], ver[N], Next[N], n, m, k, tot = 0;
void add(int u, int v, int w)
{
edge[tot] = v;
ver[tot] = w;
// 新节点插入到表头
Next[tot] = head[u];
// 上面三句为新节点初始化
// head指向新的边的编号
head[u] = tot++;
}
int main()
{
// 节点数和边数
cin >> n >> m;
// 初始化head数组为-1
memset(head, -1, sizeof head);
for(int i = 0; i < m; i++){
int u, v, w;
cin >> u >> v >> w;
// 无向图
add(u, v, w), add(v, u, w);
}
cin >> k;
// 遍历第k个节点(k >= 1)终止条件~i,i = Next[i]
for(int i = head[k]; ~i; i = Next[i]){
cout << k << " -> " << edge[i] << " 边权为:" << ver[i] << endl;
}
return 0;
}
运行结果:
1 -> 5 边权为:6
1 -> 4 边权为:5
1 -> 3 边权为:4
1 -> 2 边权为:1