資料結構【鏈式前向星】
阿新 • • 發佈:2018-12-08
第一次接觸鏈式前向星是在學習圖論的迪傑斯特拉演算法時,大佬們紛紛用鏈式前向星+堆優化+迪傑斯特拉解題,秀的我萌新懵的一批,當時不知道啥是鏈式前向星,不過隨著越來越深入,這種結構見得越來越多,慢慢的就明白了。
在儲存一個圖時,我們經常用的應該是矩陣,不過他比較浪費空間,尤其是稀疏圖,點又多,空間經常爆,所以為了解決這個問題不知道那位大佬發明了前向星這個東西,不過前向星的效率不是很高,優化後為鏈式前向星,直接介紹鏈式前向星。
結構
主要是用到一個結構體和陣列頭
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; }