链式前向星简介

最近学习数据结构和算法的时候遇到了一个棘手的问题,那就是网络流中的最大流算法,起初使用EK算法,但是最后随着数据规模的增长,好像还是要归到Dinic算法才能解决所有的问题

但是问题来了,在网上看到的几乎所有题解都是直接上了个思路,然后放一个板子,就这,但是板子看起来确实不太好懂,现在来做个科普,链式前向星,这个东西是一种数据结构,在kuangbi的模板中出现了,刚开始看的一头雾水,到后来了解到了这个东西的玄妙

简单来说,链式前向星就是一种用来存储图的数据结构,以前使用二维数组的时候会遇到的问题就是,对于稀疏图,二维数组就比较浪费空间,链式前向星借助一个结构体数组和一个数组来实现我们的功能

class node{
	private int to; //终点
	private int next;  //下一条边
	private int volume; //边的容量
	private int flow;  //边的流量
	public int getTo() {
		return to;
	}
	public void setTo(int to) {
		this.to = to;
	}
	public int getNext() {
		return next;
	}
	public void setNext(int next) {
		this.next = next;
	}
	public int getVolume() {
		return volume;
	}
	public void setVolume(int volume) {
		this.volume = volume;
	}
	public int getFlow() {
		return flow;
	}
	public void setFlow(int flow) {
		this.flow = flow;
	}
	public node(int to, int next, int volume, int flow) {
		super();
		this.to = to;
		this.next = next;
		this.volume = volume;
		this.flow = flow;
	}
	
}

这里遇到了第一个问题,我一直以为他们要记录边的起点,终点和容量,流量,但是后来发现,他压根没想记录起点,起点其实使用head[i]数组来记录,具体的操作是这样的

//count = 2;
//map就是结构体数组
//uvw分别是起点,终点,容量
public static void addnode(int u, int v, int w) {
		map[count] = new node(v, head[u], w, 0);
		head[u] = count;
		count++;
		map[count] = new node(u, head[v], 0, 0);
		head[v] = count;
		count++;
	}

那也就是说,在这条边创建的时候,我们会在结构体记录边的终点和流量,容量,同时记录了一个next,而head[u]=count,就巧妙地将起点和边关联起来,可以通过某个点i的编号寻找到以i为起点的边的信息,但是可能有聪明的小伙伴要问了:你这样只能存储最后一条边啊?
不过还在还留了一手next域,当我们输入第二条以i为起点的边,我们就会发现,原先的head[u]存储的正是前一条边的下标,此时这个下标会储存到第二条边的next域,而第二条边取代第一条边和起点建立起一个直接的联系,可想而知,我们最后获得的是一个链表数组,而我们手里的head[]数组,正是一个个链表的头节点
链式前向星简介_第1张图片

上面的图就是个示意图,黄色的线代表了原先的边的结构,黑色的线则是代表了我们使用链式前向星以后的存储结构,有了这个基础,下个博客,咱们开始梳理最大流算法EK和Dinic

你可能感兴趣的:(数据结构)