首页 > 其他分享 >图论总结

图论总结

时间:2023-10-15 10:44:58浏览次数:28  
标签:总结 图论 int void vis init 短路 dis

图论

树和图的存储

`

  1. 树是特殊的图, 无环的联通图
  2. 图分为有向图和无向图, 无向图是一种特殊的有向图
    `

邻接矩阵

存稠密图, 空间复杂度 \(O(n ^ 2)\)

g[u][v] = w;

邻接表

void init() {
	for (int i = 0; i < N; i++)
		h[i] = -1;
}

void add(int a, int b) { // 在链表头插入 b
	e[idx] = b, nt[idx] = h[a], h[a] = idx, idx++;
}

树和图的遍历

深度优先遍历

void dfs(int u) {
	vis[u] = 1; // 标记被搜过了
	for (int i = h[u]; i != -1; i = nxt[i]) { // 遍历出边
		int j = e[i];
		if(!vis[j]) dfs(j);
	}
}

宽度优先遍历

void init() {
	for (int i = 1; i <= N; i++)	
		h[i] = -1;
}

void init_() {
	for (int i = 1; i <= N; i++)
		vis[i] = -1;
}

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

int bfs() {
	init_();
	queue <int> q;
	vis[1] = 0; q.push(1);
	while (q.size()) {
		int t = q.front(); q.pop();
		for (int i = h[t]; i != -1; i = nxt[i]) {
			int j = e[i];
			if (vis[j] == -1) {
				vis[j] = vis[t] + 1;
				q.push(j);
			} 
		}
	}
	return vis[n];
}

拓扑排序

适用于 \(DAG\), 一个 \(DAG\) 至少存在一个入度为 \(0\) 的点, 拓扑序不唯一

/*
	把所有入度为 0 的点入队
	每次循环取队头 t, 枚举 t 的出边 t -> j
	删掉 t -> j, j 的入度--, d[j]--
	如果 j 的入度为 0, 将 j 入队
*/
bool topo() {
	for (int i = 1; i <= n; i++) {
		if (!d[i]) q.push(i);
	}
	while (q.size()) {
		int t = q.front(); q.pop();
		qp[++cnt] = t;
		for (int i = h[t]; i != -1; i = nxt[i]) {
			int j = e[i]; d[j]--;
			if (d[j] == 0) q.push(j);
		}
	}
	return cnt == n;
}

最短路

源点 : 起点
汇点 : 终点

Dijkstra

计算从一个点到其他所有点的最短路,
单源最短路径算法, 不能处理存在负边权的情况,
朴素 : 稠密图, 堆优化 : 稀疏图,
\(O(n^2)\)

/*
	1. 初始化距离 : dis[1] = 0, dis[i] = inf;
	2. 循环, 找到未确定最短距离的最近的点 t, 将 t 压进集合里, 用 t 更新其他点的距离 : dis[i] > dis[t] + w ? dis[t] + w : dis[i];
*/
void init() {
	for (int i = 1; i <= N; i++)
		for (int j = 1; j <= N; j++)
			e[i][j] = inf;
	for (int i = 1; i <= N; i++)
		dis[i] = inf;
	dis[1] = 0;
}

void dij() {
	for (int i = 1; i <= n; i++) {
		int t = -1;
		for (int j = 1; j <= n; j++)
			if (!vis[j] && (t == -1 || dis[t] > dis[j]))
				t = j; // 更新未确定最短路的最近的点
		vis[t] = 1;
		if (t == n) break;
		for (int j = 1; j <= n; j++)
			dis[j] = min(dis[j], dis[t] + e[t][j]);
	}
}

堆优化-Dijkstra

\(O(mlogn)\)

void init() {
	for (int i = 0; i <= N; i++)
		h[i] = -1;
	for (int i = 0; i <= N; i++)
		dis[i] = inf;
}

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

void dij() {
	dis[1] = 0;
	q.push({0, 1});
	while (q.size()) {
		int ver = q.top().second, diss = q.top().first; q.pop();
		if (vis[ver]) continue;
		vis[ver] = 1;
		for (int i = h[ver]; i != -1; i = nxt[i]) {
			int j = e[i];
			if (dis[j] > dis[ver] + w[i]) {
				dis[j] = dis[ver] + w[i];
				q.push({dis[j], j});
			}
		}
 	}
}

Bellman-Ford

单源最短路, 可以处理存在负边权的情况, 不能处理负环, 可以判断负环,
有边数限制时用 \(Bellman-Ford\),
\(O(nm)\)

/*
	1. 循环 n 次
	2. 遍历所有边 a -> b, 权值为 w : dis[b] = min(dis[b], dis[a] + w); (松弛操作)
	3. dis[b] <= dis[a] + w (三角不等式)
*/
void init() {
	for (int i = 1; i <= N; i++)
		dis[i] = inf;
}

void bellman_ford() {
	dis[1] = 0;
	for (int i = 1; i <= k; i++) {
		memcpy(backup, dis, sizeof(dis)); // 备份上一次迭代结果
		for (int j = 1; j <= m; j++) {
			int u = e[j].u, v = e[j].v, w = e[j].w;
			dis[v] = min(dis[v], backup[u] + w); // 用上一次迭代结果更新距离
		}
	}
}

Spfa

单源最短路, 可以处理存在负边权的情况, 不能处理负环,
一般 \(O(m)\), 最坏 \(O(nm)\)

/*
	1. 取出队头 t
	2. 更新 t 的所有出边
*/
void init() {
	for (int i = 1; i <= N; i++)
		h[i] = -1;
	for (int i = 1; i <= N; i++)
		dis[i] = inf;
}

void add(int u, int v, int w) {
	e[idx] = v, w[idx] = w, nxt[idx] = h[u], h[u] = idx, idx++;
}

void spfa() {
	dis[1] = 0;
	q.push(1); vis[1] = 1;
	while (q.size()) {
		int t = q.front(); q.pop();
		vis[t] = 0;
		for (int i = h[t]; i != -1; i = nxt[i]) {
			int j = e[i];
			if (dis[j] > dis[t] +w[i]) {
				dis[j] = dis[t] + w[i];
				if (!vis[j]) {
					q.push(j); vis[j] = 1;
				}
			}
		}
	}
}

Spfa 判负环

bool spfa() {
    for (int i = 1; i <= n; i++)
        vis[i] = 1, q.push(i);

    while (q.size()) {
        int t = q.front(); q.pop();
        vis[t] = 0;
        for (int i = h[t]; i != -1; i = nxt[i]) {
            int j = e[i];
            if (dis[j] > dis[t] + w[i]) {
                dis[j] = dis[t] + w[i];
                cnt[j] = cnt[t] + 1;
                if (cnt[j] >= n)
                	return true;
                if (!vis[j])
                    q.push(j), vis[j] = true;
            }
        }
    }
    return false;
}

Floyed

可求出任意两点间的最短路径,
适用于出现多源汇最短路的情况, 可以处理负边权
\(O(n^3)\)

	for (int k = 1; k <= n; k++)
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);

最小生成树

Kruskal

Prim

标签:总结,图论,int,void,vis,init,短路,dis
From: https://www.cnblogs.com/Gmor-cerr-blog/p/tulun.html

相关文章

  • ABC324总结
    ABC324solved:CDErating:UnratedC:7min(+1)D:7minE:9minCconstintN=2e5+5;\(\rightarrow\)constintN=5e5+5;。。。F01分数规划,没学过。后:就是二分答案加上推式子啊。G一眼主席树上二分。但是没调出来。码力\(\downarrow\)\(\downarrow\)\(\do......
  • 9月大型语言模型研究论文总结
    大型语言模型(llm)在今年发展迅速,随着新一代模型不断地被开发,研究人员和工程师了解最新进展变得非常重要。本文总结9-10月期间发布了一些重要的LLM论文。这些论文涵盖了一系列语言模型的主题,从模型优化和缩放到推理、基准测试和增强性能。最后部分讨论了有关安全训练并确保其行为......
  • 2023-2024-1 20231410刘珈岐 《计算机基础与程序设计》第3周学习总结
    2023-2024-120231410《计算机基础与程序设计》第3周学习总结•作业信息这个作业属于哪个课程https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP这个作业要求在哪里https://www.cnblogs.com/rocedu/p/9577842.html#WEEK03这个作业的目标自学计算机科学概论第......
  • 2023-2024-1学期 20231302邱之钊 《计算机基础与程序设计》第三周学习总结
    作业信息作业属于的课程2023-2024-1-计算机基础与程序设计作业要求2023-2024-1计算机基础与程序设计第一周作业作业目标数字分类与计数法、位置计数法、进制转换、模拟数据与数字数据、压缩与解压、数字化、信息安全作业正文2023-2024-1学期20231302邱之钊《......
  • 2023-2024-1 20231406 《计算机基础与程序设计》第3周学习总结
    2023-2024-120231406《计算机基础与程序设计》第3周学习总结作业信息这个作业属于哪个课程<班级的链接>(如[2023-2024-1-计算机基础与程序设计](https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP)这个作业要求在哪里<作业要求的链接>(如2023-2024-1计算机基础......
  • 每日总结
    数的表示机器数:各种数值在计算机中表示的形式,其特点是使用二进制计数制,数的符号用0和1表示,小数点则隐含,不占位置。机器数有无符号数和带符号数之分。无符号数表示正数,没有符号位。带符号数最高位为符号位,正数符号位为0,负数符号位为1。定点表示法分为纯小数和纯整数两种,其中小数......
  • 2023-2024-1 20231329《计算机基础与程序设计》第3周学习总结
    作业信息这个作业属于哪个课程https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP这个作业要求在哪里https://www.cnblogs.com/rocedu/p/9577842.html#WEEK03这个作业的目标 计算机科学概论第2章,第3章并完成云班课测试《C语言程序设计》第2章并完成云班课......
  • 2023-2024-1 20231424 《计算机基础与程序设计》第3周学习总结
    作业信息作业课程2022-2023-1-计算机基础与程序设计作业要求2022-2023-1计算机基础与程序设计第一周作业这个作业的目标自学《计算机科学概论》第2章,第3章和《C语言程序设计》第2章作业正文链接https://www.cnblogs.com/2004lby/p/17764649.html教材学习内......
  • Linux常见配置文件总结
    /etc/passwd:这个文件包含了系统上的用户账户信息,如用户名、用户ID、用户所属组ID、用户主目录等。/etc/shadow:该文件存储了用户账户的密码哈希值和其他安全相关设置,只有root用户及授权用户可以访问。/etc/group:该文件记录了用户组的信息,包括组名、组ID和组成员。/etc/hosts:这个文件......
  • 关于Cortex-M3报错解决方法总结:Flash Download failed错误
    事情原因:在一次使用ST-LINKv2下载程序时,突然出现Error:FlashDownloadFailed-"Cortex-M3”这个错误,显示没有错误,没有警告。芯片型号接线都没有问题。当时就很摸不着头脑,然后上网查看了一下。原来是因为STM32F103C8T6有64kFlash和20kRAM,tm他们不属于高容量的Flash。所以我改了......