图论基础理论与实际应用详解(C++实现)
一、基本概念
图 $G$ 由顶点集 $V$ 和边集 $E$ 构成,记为 $G=(V,E)$。
- 有向图:边有方向,$E \\subseteq V \\times V$
- 无向图:边无方向,$E$ 为无序对集合
- 权重图:边附加权值函数 $w: E \\to \\mathbb{R}$
存储结构:
const int MAXN = 1000;
int graph[MAXN][MAXN]; // 权重存于矩阵
#include <vector>
using namespace std;
struct Edge {
int to;
int weight;
};
vector<vector<Edge>> adjList; // adjList[i]存储顶点i的邻接边
二、图的遍历算法
深度优先搜索(DFS)
vector<bool> visited;
void dfs(int u) {
visited[u] = true;
for (auto& edge : adjList[u]) {
if (!visited[edge.to]) {
dfs(edge.to);
}
}
}
https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MDQ4MS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MDcwMi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1Mjk4MS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1Mjk4My5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1Mjk4NS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzIyMS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzIyNC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzMxOC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzIzMi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzE3Ni5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzA3Ny5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzIzOS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzI0NC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzI1MC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzE5Ny5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzM0Ni5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzI1OS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzUwNS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzI2OC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzUxMy5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzQxMi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzM2Ni5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzQyMy5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzUzMC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzUzMS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzI5My5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzQzNi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzYwMy5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5NTk1MzAwMy5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDM4OTIwMjE2LzY5NTk1MjkzOS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5NTk1MDk0Ny5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5NTk1MTAyMi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5NTk1Mjc0OC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5NTk1MjY2Mi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5NTk1MjkyOS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDM4OTIwMjE2LzY5NTk1MjY2MS5zaHRtbA==.html
应用场景:连通分量检测、拓扑排序、回溯法
广度优先搜索(BFS)
#include <queue>
void bfs(int start) {
queue<int> q;
q.push(start);
visited[start] = true;
while (!q.empty()) {
int u = q.front();
q.pop();
for (auto& edge : adjList[u]) {
if (!visited[edge.to]) {
visited[edge.to] = true;
q.push(edge.to);
}
}
}
}
应用场景:最短路径(无权图)、层级遍历
三、经典问题与算法
1. 最短路径(Dijkstra算法)
核心思想:贪心策略,适用于非负权图 $$d[v] = \\min(d[u] + w(u,v))$$
#include <queue>
#include <climits>
vector<int> dijkstra(int src, int n) {
vector<int> dist(n, INT_MAX);
dist[src] = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push({0, src});
while (!pq.empty()) {
auto [d, u] = pq.top();
pq.pop();
if (d != dist[u]) continue; // 旧数据跳过
for (auto& edge : adjList[u]) {
int newDist = d + edge.weight;
if (newDist < dist[edge.to]) {
dist[edge.to] = newDist;
pq.push({newDist, edge.to});
}
}
}
return dist;
}
2. 拓扑排序(Kahn算法)
适用条件:有向无环图(DAG) $$ \\text{入度} \\operatorname{deg}^{-}(v) = 0 \\implies \\text{可移除} $$
vector<int> topologicalSort(int n) {
vector<int> indegree(n, 0);
vector<int> result;
queue<int> q;
// 计算入度
for (int u = 0; u < n; u++)
for (auto& edge : adjList[u])
indegree[edge.to]++;
// 入度为0入队
for (int i = 0; i < n; i++)
if (indegree[i] == 0) q.push(i);
while (!q.empty()) {
int u = q.front();
q.pop();
result.push_back(u);
for (auto& edge : adjList[u]) {
if (–indegree[edge.to] == 0)
q.push(edge.to);
}
}
return result.size() == n ? result : vector<int>{}; // 判断环
}
https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MDQ4MS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MDcwMi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1Mjk4MS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1Mjk4My5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1Mjk4NS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzIyMS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzIyNC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzMxOC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzIzMi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzE3Ni5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzA3Ny5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzIzOS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzI0NC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzI1MC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzE5Ny5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzM0Ni5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzI1OS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzUwNS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzI2OC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzUxMy5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzQxMi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzM2Ni5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzQyMy5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzUzMC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzUzMS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzI5My5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzQzNi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkzMDExLzY5NTk1MzYwMy5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5NTk1MzAwMy5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDM4OTIwMjE2LzY5NTk1MjkzOS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5NTk1MDk0Ny5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5NTk1MTAyMi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQyMDkyMzY0LzY5NTk1Mjc0OC5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5NTk1MjY2Mi5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDQxNTQ4MjkwLzY5NTk1MjkyOS5zaHRtbA==.html https://tv.sohu.com/v/dXMvNDM4OTIwMjE2LzY5NTk1MjY2MS5zaHRtbA==.html
3. 最小生成树(Prim算法)
目标:连接所有顶点的最小权重边集 $$ T \\subseteq E, \\quad \\min \\sum_{e \\in T} w(e) $$
int prim(int n) {
vector<bool> visited(n, false);
vector<int> minDist(n, INT_MAX);
minDist[0] = 0;
int total = 0;
for (int i = 0; i < n; i++) {
int u = -1;
for (int j = 0; j < n; j++) // 选最小未访问点
if (!visited[j] && (u == -1 || minDist[j] < minDist[u]))
u = j;
if (minDist[u] == INT_MAX) return -1; // 不连通
visited[u] = true;
total += minDist[u];
for (auto& edge : adjList[u])
if (edge.weight < minDist[edge.to])
minDist[edge.to] = edge.weight;
}
return total;
}
四、实际应用场景
路径规划
- 导航系统(Dijkstra/A*算法)
- 物流配送(带时间窗的最短路径)
依赖分析
- 编译顺序(拓扑排序)
- 任务调度(关键路径法)
网络优化
- 通信网布线(最小生成树)
- 最大流问题(Ford-Fulkerson算法)
五、复杂问题扩展
- 负权处理:Bellman-Ford算法(动态规划)
- 全源最短路径:Floyd-Warshall算法(三重循环)
- 图的连通性:Tarjan强连通分量算法
提示:实际编码需处理边界条件(如不连通图、自环边),建议使用C++ STL的priority_queue优化Dijkstra,时间复杂度降至 $O(|E|\\log|V|)$。
网硕互联帮助中心



评论前必须登录!
注册