专栏文章

图论算法

科技·工程参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mioyyi6t
此快照首次捕获于
2025/12/03 03:26
3 个月前
此快照最后确认于
2025/12/03 03:26
3 个月前
查看原文

DayDay 55:恍然发现,集训已经过了13\frac 1 3

由于这两天都学习的是图论算法其实是昨晚打了ABC,所以整合到了今天一天来写。

要学习图论算法,首先要了解什么是图

图分为节点和边,在日常的学习中,我们常简记为G=(V,E)G = (V, E)。特别的,如果一个图中任意两个结点都有路径相连,则称其为:连通图(无向)强连通图(有向)

数据篇:

图的存储:

主要依靠邻接矩阵邻接表(还有慢慢淡出人们视线的链式前向星)来存储图
邻接矩阵依靠的是使用二维数组来存储,如果某两个点间没有路径,通常使用一个很大的数字来代替(如INT_MAX、0x7fffffffff)。我们便有了如下代码:
CPP
int n, m;
int a[1010][1010];
int main()
{
	// 初始化 
	for(int i = 1;i <= 1000; i++) {
		a[i][j] = INT_MAX;
	}
	cin >> n >> m;
	for(int i = 1;i <= m; i++) {
		cin >> a[i][j];
		// 若是无向图 则加上 a[j][i] = a[i][j] 即可 
	}
	return 0;
}

领接矩阵的优点和缺点:

优点:便于存储和使用(较入门)
缺点:费空间,只有题目范围小的时候才能使用或只拿部分分(尤其指点多边少的情况)

邻接表一般使用一个动态数组Vector<edge>e[maxn]Vector<edge> e[maxn]来存储,其中edgeedge是一个存储点(vv)和边权值(ww)的结构体。本质上是链试存图,存储的是点能直接到达的点:
CPP
struct edge
{
	int v, w;
};
vector<edge> e[maxn];
int main()
{
	cin >> n >> m;
	for(int i = 1;i <= m; i++)
	{
		int a, b, c;
		cin >> a >> b >> c;
		e[a].push_back({b, c});
		// 同样 无向图的加上 e[b].push_back({a, c}) 即可 
	}
        return 0;
}

领接表的优点和缺点:

优点:可以处理大数据
缺点:用法较进阶,不易上手
图的存储中,需要特殊处理的是有无重边(有重复的、多余的边)自环(单个结点的起点和终点都是自己)代码就不在此实现了因为本蒟蒻特别的懒:D

算法篇

特此声明:由于算法代码较长,在此不一一展出,有感兴趣的大佬可自行代码或查阅。

拓扑排序

依次输出没有入度的点。
使用条件:有向无环图(DAGDAG)。
算法思路:1、选择一个没有入度的点;2、删除已遍历过的边和点。

最小生成树(MSTMST

首先我们要清楚:当一个无向连通图有nn个点,n1(n-1)条边的话——它就是树! 最小生成树算法实现的就是通过删除某些边和点,使最终的图变成一棵边权加起来最小的树。
主要算法有KruskalKruskal(克鲁斯卡尔)和PrimPrim(普利姆)算法。
KruskalKruskal算法是依次选取最短的边,如果形成环则舍弃,没有形成环就添加,时间复杂度为O(mlogn)O(mlogn)
PrimPrim算法是依据随机一个起点,松弛其周围最近的边,再用下一个点继续松弛操作,直到所有的点都被遍历。所有被松弛的边和点即为该图的最小生成树。
(看到这里的大佬想必已经知道这两种算法是基于贪心思想了)

最短路径问题

终于快写完了!!!
目前来说,最短路径问题较主流的由DijkstraDijkstra(迪杰斯特拉)算法、SpfaSpfa算法、FloydFloyd(弗洛伊德)算法。
DijkstraDijkstra算法是目前图论中用途最广,适用题目最多(变形最方便),复杂度最稳定的一种算法,核心思想是取一个原点,遍历其与其他结点相连的边,并在后来的遍历中不断更新到其他结点的路径最小值。 同时,它的缺点也很明显:1、无法处理负边负环;2、题目需要满足贪心性质(;3、无法求最长路)。
SpfaSpfa算法是用途较为广泛,可以处理负边负环,但是时间复杂度不稳定(容易被卡)的一种算法。算法的核心逻辑是通过多层循环并剪枝优化,找到原点与各个结点间路径最小值的一种算法。
FloydFloyd算法是逻辑与代码较简单,可以同时求多源最短路,但是时间复杂度较高(O(N3))(O(N^3))的一种算法。算法结合动态规划,通过枚举结点与结点之间,比较之间插入另一个中继点与原路径长的关系,从而达到同时求出多源最短路的问题。

结语

今天也恰好是出中考成绩的一天,借用我的教练送给我的一句话: 分数代表过去,积极准备,开始新的挑战!

评论

0 条评论,欢迎与作者交流。

正在加载评论...