
你好 (=´ω`=)
已经是2026年啦,我们已经度过了我们一生中唯一一个立方和年了....
因为某种原因,跨年那天没有发文章,不过我的作品突破了50赞。
这里还是要感谢大家一直以来的支持,祝大家2026也要开开心心哦 φ(>ω<*)
目录
你好,图论
如果你正在学习C++,又对算法感兴趣,我想你已经听说过 "图论" 这个名字了。
也许你觉得它复杂,但其实它很温柔-一就像我们用代码描述世界的一种安静方式。
什么是图?
图,其实就是一些点和连接这些点的线。
点我们叫 "顶点" ,线我们叫 "边" 。
现实中有太多图的身影了:
- 你的微信好友关系是一个图
- 地图上的地点和道路是一个图
- 网页之间的链接也是一个图
在C++中表示图
我们有几种简单的方法来告诉计算机,我们的图是什么样子的。
邻接表:朋友链表
为每个顶点准备一个列表,记录它的所有邻居:
cpp
#include <vector>
using namespace std;
// 创建有5个顶点的图
int n = 5;
vector<vector<int>> graph(n);
// 添加一条从顶点0到顶点1的边
graph[0].push_back(1);
// 如果需要无向图,就添加两次
graph[0].push_back(1);
graph[1].push_back(0);
邻接表很节省空间,特别适合朋友不太多的顶点。
邻接矩阵:关系表
用一个二维表格记录每对顶点是否相连:
cpp
#include <vector>
using namespace std;
int n = 5;
// 创建n×n的表格,初始为false
vector<vector<bool>> matrix(n, vector<bool>(n, false));
// 连接顶点0和1
matrix[0][1] = true;
// 如果是无向图
matrix[1][0] = true;
// 检查0和1是否相连
if (matrix[0][1]) {
cout << "0和1是相连的" << endl;
}
拜访图中的每一个顶点
深度优先搜索(DFS)
沿着一条路走到底,再慢慢返回:
cpp
void dfs(int node, vector<bool>& visited, vector<vector<int>>& graph) {
visited[node] = true;
cout << "拜访顶点: " << node << endl;
for (int neighbor : graph[node]) {
if (!visited[neighbor]) {
dfs(neighbor, visited, graph);
}
}
}
广度优先搜索(BFS)
一层一层地向外探索:
cpp
#include <queue>
void bfs(int start, vector<vector<int>>& graph) {
int n = graph.size();
vector<bool> visited(n, false);
queue<int> q;
visited[start] = true;
q.push(start);
while (!q.empty()) {
int current = q.front();
q.pop();
cout << "拜访顶点: " << current << endl;
for (int neighbor : graph[current]) {
if (!visited[neighbor]) {
visited[neighbor] = true;
q.push(neighbor);
}
}
}
}
一些简单的图论算法
最短路径(Dijkstra算法)
找到从一个点到其他所有点的最短距离:
cpp
#include <queue>
#include <climits>
vector<int> dijkstra(int start, vector<vector<pair<int, int>>>& graph) {
int n = graph.size();
vector<int> distance(n, INT_MAX);
priority_queue<pair<int, int>> pq; // 优先队列
distance[start] = 0;
pq.push({0, start});
while (!pq.empty()) {
int dist = -pq.top().first; // 取负值实现最小堆
int node = pq.top().second;
pq.pop();
if (dist > distance[node]) continue;
for (auto& edge : graph[node]) {
int neighbor = edge.first;
int weight = edge.second;
if (distance[node] + weight < distance[neighbor]) {
distance[neighbor] = distance[node] + weight;
pq.push({-distance[neighbor], neighbor});
}
}
}
return distance;
}
从一个小例子开始
让我们实现一个简单的社交网络分析:
cpp
#include <iostream>
#include <vector>
#include <queue>
class SocialNetwork {
private:
vector<vector<int>> friends;
public:
SocialNetwork(int n) : friends(n) {}
void addFriendship(int a, int b) {
friends[a].push_back(b);
friends[b].push_back(a);
}
// 找到两个人的最短关系链长度
int findConnectionLevel(int person1, int person2) {
int n = friends.size();
vector<bool> visited(n, false);
queue<pair<int, int>> q; // (人, 距离)
visited[person1] = true;
q.push({person1, 0});
while (!q.empty()) {
auto [current, dist] = q.front();
q.pop();
if (current == person2) {
return dist;
}
for (int friendId : friends[current]) {
if (!visited[friendId]) {
visited[friendId] = true;
q.push({friendId, dist + 1});
}
}
}
return -1; // 没有找到连接
}
};
给初学者的建议
- 从简单的开始:先理解邻接表和邻接矩阵
- 动手实现:不要只看代码,自己写一遍
- 画图帮助理解:在纸上画出小规模的图
- 调试观察:用小的测试数据跟踪程序执行
最后想说
图论并不像看起来那么难。
每个复杂的算法都是由简单的想法组成的。
在C++中实现图论算法,就像是教计算机如何观察和理解关系。
你可以从小的练习开始,比如计算你朋友圈中的共同好友,或者找出从宿舍到教室的所有路径。
一点一点地,你会发现图论其实是很有逻辑的,甚至是有点优美的。
希望这些简单的介绍能帮助你开始。
学习编程的路上,我们都慢慢来,每一步都算数。
如果您看到这里请点赞关注支持一下吧✧*。٩(ˊᗜˋ*)و✧*。