算法初探 - 鏈式前向星

更新記錄

【1】2020.05.20-00:27ios

1.完善內容數組

正文

在學習圖論的時候,你首先要學習的就是圖的存儲
鄰接矩陣佔空間太大
前向星效率不是很高
因而乎咱們就開始使用鏈式前向星學習

存儲

鏈式前向星使用結構體數組存邊spa

struct edge{
	int nextarray;
	int nextpoint;
	int w;
};

\(edge[i]\)表示全部已存儲的邊中的第i條邊
\(head[i]\)表示以\(i\)爲起點的全部邊中的第一條
\(nextarray\)表示下一條邊的數組下標
\(nextpoint\)表示這條邊的終點
\(w\)表示權值code

添加

void add(int from,int to,int w){
	edge[++num].nextarray=head[from];
	edge[num].nextpoint=to;
	edge[num].w=w;
	head[from]=num;
}

首先咱們要明白,添加邊時爲倒序添加
也就是說,按遍歷的順序來看,第一條邊最後才被遍歷到,新加的這條邊反而是第一條要進行遍歷邊ci

那麼咱們首先讓\(num\)自增,表示全部邊的條數+1(\(++num\)io

因爲是倒序添加,因此原來最早要訪問的邊變成了第二條要訪問的邊class

  • 咱們先讓新添加的邊的下一條邊的數組下標改成當前最早要訪問的邊的數組下標
    \((edge[++num].nextarray=head[from])\)
  • 而後把最早要訪問的邊的數組下標改成新添加的邊的數組下標
    \((head[from]=num)\)

終點與權值不變,原樣複製過去效率

遍歷

經過觀察發現,第一條邊在添加時\(head[from]\)爲0
因此其nextarray爲0stream

這能夠用來看成程序終止的條件

因此咱們遍歷以i爲起點的全部邊就能夠這麼寫:

for(int o=head[i];o!=0;o=edge[o].nextarray)

o!=0意爲只要沒到最後一條邊,就繼續往下遍歷

完整程序

#include<iostream>
using namespace std;
struct Edge{
	int nexta;
	int nextp;
	int w;
}edge[1001];
int num,head[1001],n,f,t,m,w;
inline void add(int from,int to,int w){
	edge[++num].nexta=head[from];
	edge[num].nextp=to;edge[num].w=w;
	head[from]=num;
}
int main(){
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>f>>t>>w;add(f,t,w);
	}
	for(int i=1;i<=m;i++)
		for(int o=head[i];o!=0;o=edge[o].nexta)
			cout<<i<<"->"<<edge[o].nextp<<" "<<edge[o].w<<"\n";
}

注意若是是無向圖時,同一條邊要存儲兩遍,即兩個方向各存一遍

相關文章
相關標籤/搜索