Day 7 树与二叉树、图论

树的定义与概念

image

image


 

image


 

image


 

image

image

树的表示与存储

image

image

二叉树

image

image

image

image

image

image


 

image

image

二叉树的遍历

image

图论

图的定义和概念

image


 

image


 

image


 

image


 

image


 

image


 

image


 

image


 

image


 

image

image

图的存储

image

image

图的遍历

image

最短路径问题 Dijkstra

image


 

image


 

image


 

image


 

image


 

image


 

image

image

经典例题:

#include <bits/stdc++.h>
using namespace std;

// 1. 存图,边的信息保存 vector 数组

// 2. Dijkstra 算法:建立距离起点的表格,把所有的距离初始化为 inf (无穷远),起点标记为 0

// 			a. 提取距离起点最近的顶点(未访问)

// 			b. 求它可以去的所有顶点 最短值计算 road,road < d[顶点] 更新最短路径

//   		c. 重复 a,b 直到所有的顶点没有扩散的点

// 3. 得到 d 数组 距离起点的所有顶点的最短距离
struct EDGE {
	int v, w;		// 到达的 v 终点,w 权值,v 表示顶点的编号,w 还表示 d[v] 距离 
	bool operator < (const EDGE &a) const {
		return a.w < w;	// w 值越小的 排在前面 
	}
};
const int MAXN = 2e5 + 5;
vector<EDGE> g[MAXN];				// 最多 2e5 个顶点
int n, m, s, t, dist[MAXN];			// n 个顶点,m 条边,s 起点,t 终点,dist 记录起点到其他所有点最短距离 distance 

void Dij() {
	// 建立距离起点的表格,把所有的距离初始化为 inf (无穷远),起点标记为 0
	memset(dist, 0x3f, sizeof(dist));
	dist[s] = 0;
	
	priority_queue<EDGE> q;			// 优先队列,每次提取距离起点最近的顶点
	q.push({s, dist[s]}); 			// 把起点和到起点的距离放入优先队列
	while (!q.empty()) {
		// a. 提取距离起点最近的顶点(未访问)
		EDGE now = q.top(); q.pop();// 取出最近的距离
		int u = now.v, w = now.w;	// 这个顶点编号保存 u,s 到 u 距离是 w
		if (w > dist[u]) continue;	// 当此时这个顶点的 w 比现在记录 dist[u] 还要远,没有意义的扩展
		
		// b. 求它可以去的所有顶点 最短值计算 road,road < d[顶点] 更新最短路径
		for (auto e : g[u]) {
			int v = e.v, road = dist[u] + e.w;	// 先从起点走到这个 u 点,从 u 点走到 v
			if (road < dist[v]) {				// 发现此时走这条路更进 
				dist[v] = road;
				q.push({v, dist[v]});			// 松弛操作,将这个更新的点放入到优先队列中 
			}
		}
	}
} 

int main() {
	// 1. 存图,边的信息保存 vector 数组
	cin >> n >> m >> s >> t;		// 按照顺序输入
	for (int i = 0; i < m; i++) {
		int a, b, c;
		cin >> a >> b >> c;			// 起点 a 到 b 距离需要 c 
		g[a].push_back({b, c});
		g[b].push_back({a, c});		// 双向图从 b 到 a 需要 c 
	}
	// 2. Dijkstra 算法
	Dij();
	// 3. 得到 d 数组 距离起点的所有顶点的最短距离 起点 s 到 t 最短距离
	cout << dist[t];				// t 点距离 s 点最短距离 
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值