链式前向星核心代码解析 ← 数组模拟邻接表

本文介绍了在算法竞赛中,如何通过链式前向星数据结构优化SPFA、DFS和BFS的性能。相比于STL vector,链式前向星以数组模拟邻接表,减少内存操作,特别适合处理网络流问题和避免超时。核心代码和示例展示了如何在有权图中实现链式前向星并进行深度优先和广度优先搜索。
摘要由CSDN通过智能技术生成

【知识点】
在图论算法实现中,常使用C++标准库
STL自带的vector来模拟邻接表存图。详见:
https://blog.csdn.net/hnjzsyjyj/article/details/101233779
https://blog.csdn.net/hnjzsyjyj/article/details/101233485
https://blog.csdn.net/hnjzsyjyj/article/details/101233249
但是,在算法竞赛中,使用C++标准库
STL自带的vector来模拟邻接表存图的方法,对某些复杂问题会超时。此外,在处理网络流问题中的构建反向边等操作时会麻烦一些。据此,可引入链式前向星这种用数组模拟邻接表存图的优秀数据结构。

本质上,链式前向星是以存储边的方式来存储图。换句话说,链式前向星是一种特殊的
边集数组
链式前向星特别适合用来优化 
SPFADFSBFS

链式前向星的核心代码如下所述。其中:

val[idx]:存储编号为 idx 的边的
e[idx]:存储编号为 idx 的结点的
ne[idx]:存储编号为 idx 的结点指向的结点的编号
h[a]:存储头结点 a 指向的结点的编号

在上述约定下,则有:
● 链式前向星的核心代码如下:

void add(int a,int b) {
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

如果是有权图,需多设置一个数组 val[] 存储权值。有权图的链式前向星的核心代码如下:

void add(int a,int b,int w) {
	val[idx]=w,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

● 基于链式前向星的深度优先搜索(DFS)的核心代码如下:

void dfs(int u) {
	cout<<u<<" ";
	st[u]=true;
	for(int i=h[u]; ~i; i=ne[i]) { //~i; equivalent to i!=-1;
		int j=e[i];
		if(!st[j]) {
			dfs(j);
		}
	}
}

● 基于链式前向星的广度优先搜索(BFS)的核心代码如下:

void bfs(int u) {
	queue<int>q;
	st[u]=true;
	q.push(u);
	while(!q.empty()) {
		int t=q.front();
		q.pop();
		cout<<t<<" ";
		for(int i=h[t]; ~i; i=ne[i]) { //~i; equivalent to i!=-1;
			int j=e[i];
			if(!st[j]) {
				q.push(j);
				st[j]=true; //need to be flagged immediately after being queued
			}
		}
	}
}



【参考文献】
https://zhuanlan.zhihu.com/p/343092172
https://malash.me/200910/linked-forward-star/
https://www.acwing.com/solution/content/124095/
https://blog.csdn.net/hnjzsyjyj/article/details/119917795
https://blog.csdn.net/hnjzsyjyj/article/details/103778724




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值