第一次接触链式前向星是在学习图论的迪杰斯特拉算法时,大佬们纷纷用链式前向星+堆优化+迪杰斯特拉解题,秀的我萌新懵的一批,当时不知道啥是链式前向星,不过随着越来越深入,这种结构见得越来越多,慢慢的就明白了。
在存储一个图时,我们经常用的应该是矩阵,不过他比较浪费空间,尤其是稀疏图,点又多,空间经常爆,所以为了解决这个问题不知道那位大佬发明了前向星这个东西,不过前向星的效率不是很高,优化后为链式前向星,直接介绍链式前向星。
结构
主要是用到一个结构体和数组头
struct Edge{
int next,to,w;//下一条边的储存下标,这条边的终点,权值
};
Edge edge[500010];
结构体数边缘存边,边[i]表示第i条边,头[i]存以我为起点的第一条边(在边中的下标)。
增边
若以点我为起点的边新增了一条,在边缘中的下标为Ĵ,那么边缘[J]的.next =头[I];然后头[I] = j的,即每次新加的边作为第一条边,最后倒序遍历
void Add(int u, int v, int w) {
edge[++cnt].next = head[u];//cnt为计数,从1开始
edge[cnt].to = v;
edge[cnt].w = w;
head[u] = cnt;//第一条边为当前边
}
遍历
遍历以小号为起点的边
for(int i=head[s]; i!=0; i=edge[i].next)
我开始为第一条边,每次指向下一条(以0为结束标志)(若下标从0开始,下应应初始化-1)
例题:洛谷P3371
#include<bits/stdc++.h>
const long long inf=2147483647;
const int maxn=10005;
const int maxm=500005;
using namespace std;
int n,m,s,num_edge=0;
int dis[maxn],vis[maxn],head[maxm];
struct Edge{
int next,to,dis;
}edge[maxm]; //结构体表示静态邻接表
void addedge(int from,int to,int dis){
edge[++num_edge].next=head[from];
edge[num_edge].to=to;
edge[num_edge].dis=dis;
head[from]=num_edge;
}
void spfa(){
queue<int>q;
for(int i=1; i<=n; i++) {
dis[i]=inf;
vis[i]=0;
}
q.push(s);
dis[s]=0;vis[s]=1;
while(!q.empty()){
int u=q.front();q.pop();
vis[u]=0;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].dis){
dis[v]=dis[u]+edge[i].dis;
if(vis[v]==0) {
vis[v]=1;
q.push(v);
}
}
}
}
}
int main(){
cin>>n>>m>>s;
for(int i=1; i<=m; i++){
int f,g,w;
cin>>f>>g>>w;
addedge(f,g,w);
}
spfa();
for(int i=1; i<=n; i++)
if(s==i) cout<<0<<" ";
else cout<<dis[i]<<" ";
return 0;
}