算法初探

更新记录

【1】2020.05.20-00:27

1.完善内容

正文

在学习图论的时候,你首先要学习的就是图的存储
邻接矩阵占空间太大
前向星效率不是很高
于是乎我们就开始使用链式前向星

存储

链式前向星使用结构体数组存边

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

(edge[i])表示所有已存储的边中的第i条边
(head[i])表示以(i)为起点的所有边中的第一条
(nextarray)表示下一条边的数组下标
(nextpoint)表示这条边的终点
(w)表示权值

添加

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

首先我们要明白,添加边时为倒序添加
也就是说,按遍历的顺序来看,第一条边最后才被遍历到,新加的这条边反而是第一条要进行遍历边

那么我们首先让(num)自增,表示所有边的条数+1((++num)

由于是倒序添加,所以原来最先要访问的边变成了第二条要访问的边

  • 我们先让新添加的边的下一条边的数组下标改为当前最先要访问的边的数组下标
    ((edge[++num].nextarray=head[from]))
  • 然后把最先要访问的边的数组下标改为新添加的边的数组下标
    ((head[from]=num))

终点与权值不变,原样复制过去

遍历

通过观察发现,第一条边在添加时(head[from])为0
所以其nextarray为0

这可以用来当作程序终止的条件

所以我们遍历以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<<"
";
}

注意如果是无向图时,同一条边要存储两遍,即两个方向各存一遍

原文地址:https://www.cnblogs.com/zythonc/p/12920663.html