链式前向星
在了解什么是链式前向星之前,我们先来看一下什么是前向星。
前向星其实就是一种边集数组。我们先把每条边的起点按照从小到大的顺序排序如果起点一样,那么就按照终点从小到达来排序。并记录下以某个点为起点的所有边在数组中的起始位置和边的数量,那么前向星就构造好了。
利用前向星,我们可以在O(1)的时间内找到以i为起点的第一条边以O(len[i])的时间找到以i为起点的所有边。前向星特别适合用
来优化SPFA(一种最短路算法),DFS以及BFS(深度优先搜索和宽度优先搜索)。
但是前向星还是需要加上排序的时间的,如果是快排大概是O(n*log(n)); 而链式前向星则不需要排序也能够得到。
我们用head[i]表示以i为起点的最后一条边的储存位置,next[i]表示与第i条边同起点的上一条边的储存位置,e[i]表示第i条边的终点。
加边:
struct Edge
{
int next ;
int e;
int w;
} edge [ MAXN ];
edge[i].next表示同起点的下一条边,edge[i].e代表这条边的终点,edge[i].w为权值。
void add (int u,int v,int w)
{
edge [cnt ].w = w;
edge [cnt ].e = v;
edge [cnt ].next = head [u];
head [u] = cnt ++;
}
cnt初始化为一,head数组初始化为0.
完整代码如下:
#include <bits/stdc++.h>
using namespace std;
#define MAXN 100000
struct EDGE
{
int next;//同起点的上一条边的位置
int e;//边的终点
int w;//权值
}edge[MAXN];
int cnt=1;
int head[MAXN];//以i为起点的最后一条边
void add(int u,int v,int w)
{
edge[cnt].w=w;
edge[cnt].e=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
int main()
{
memset(head,0,sizeof(head));
int a,b,n,c;
cin>>n;//输入边的数量
while(n--)
{
cin>>a>>b>>c;
add(a,b,c);
}
cout<<"请输入要查询的边的起点:";
int i;//要查询的边
cin>>i;
for(int j=head[i];j!=0;j=edge[j].next)
{
cout<<i<<"->"<<edge[j].e<<endl;
}
return 0;
}