图论简述+图论考试要点(C++)

图论基本概念

图论是研究图(Graph)的数学理论,图由**顶点(Vertex)边(Edge)**组成,用于表示对象及其关系。

  • 无向图:边无方向,用无序对 (u, v) 表示。
  • 有向图:边有方向,用有序对 (u \\to v) 表示。
  • 权重图:边附带权值,常用于路径优化问题。
  • 常见术语:度(Degree)、路径(Path)、环(Cycle)、连通性(Connectedness)。

图的存储方式(C++实现)

邻接矩阵

适用于稠密图,空间复杂度 O(V\^2)

cpp 复制代码
const int MAX_V = 100;
int adjMatrix[MAX_V][MAX_V]; // 初始化为0或INF
邻接表

适用于稀疏图,空间复杂度 O(V + E)

cpp 复制代码
#include <vector>
vector<int> adjList[MAX_V]; // 无权重
vector<pair<int, int>> weightedAdjList[MAX_V]; // 带权重

图遍历算法

深度优先搜索(DFS)

递归或栈实现,用于连通性检测、拓扑排序等。

cpp 复制代码
bool visited[MAX_V];
void dfs(int u) {
    visited[u] = true;
    for (int v : adjList[u]) {
        if (!visited[v]) dfs(v);
    }
}
广度优先搜索(BFS)

队列实现,用于最短路径(无权图)。

cpp 复制代码
queue<int> q;
bool visited[MAX_V];
void bfs(int start) {
    q.push(start);
    visited[start] = true;
    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (int v : adjList[u]) {
            if (!visited[v]) {
                visited[v] = true;
                q.push(v);
            }
        }
    }
}

最短路径算法

Dijkstra算法

适用于非负权图,时间复杂度 O((V + E) \\log V)

cpp 复制代码
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
vector<int> dist(MAX_V, INF);
void dijkstra(int start) {
    dist[start] = 0;
    pq.push({0, start});
    while (!pq.empty()) {
        auto [d, u] = pq.top(); pq.pop();
        if (d > dist[u]) continue;
        for (auto [v, w] : weightedAdjList[u]) {
            if (dist[v] > dist[u] + w) {
                dist[v] = dist[u] + w;
                pq.push({dist[v], v});
            }
        }
    }
}
Floyd-Warshall算法

动态规划实现,适用于所有节点对的最短路径,时间复杂度 O(V\^3)

cpp 复制代码
int dist[MAX_V][MAX_V];
void floydWarshall(int V) {
    for (int k = 0; k < V; ++k)
        for (int i = 0; i < V; ++i)
            for (int j = 0; j < V; ++j)
                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
}

最小生成树(MST)

Kruskal算法

基于并查集,时间复杂度 O(E \\log E)

cpp 复制代码
struct Edge { int u, v, w; };
vector<Edge> edges;
int parent[MAX_V];

int find(int u) { return parent[u] == u ? u : parent[u] = find(parent[u]); }

int kruskal() {
    sort(edges.begin(), edges.end(), [](Edge a, Edge b) { return a.w < b.w; });
    for (int i = 0; i < MAX_V; ++i) parent[i] = i;
    int total = 0;
    for (Edge e : edges) {
        int pu = find(e.u), pv = find(e.v);
        if (pu != pv) {
            parent[pu] = pv;
            total += e.w;
        }
    }
    return total;
}
Prim算法

优先队列实现,时间复杂度 O(E \\log V)

cpp 复制代码
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
bool inMST[MAX_V];
int prim() {
    pq.push({0, 0});
    int total = 0;
    while (!pq.empty()) {
        auto [w, u] = pq.top(); pq.pop();
        if (inMST[u]) continue;
        inMST[u] = true;
        total += w;
        for (auto [v, weight] : weightedAdjList[u]) {
            if (!inMST[v]) pq.push({weight, v});
        }
    }
    return total;
}

拓扑排序

适用于有向无环图(DAG),基于DFS或BFS(Kahn算法)。

cpp 复制代码
vector<int> topoSort(int V) {
    vector<int> inDegree(V, 0), result;
    for (int u = 0; u < V; ++u)
        for (int v : adjList[u]) inDegree[v]++;
    queue<int> q;
    for (int u = 0; u < V; ++u)
        if (inDegree[u] == 0) q.push(u);
    while (!q.empty()) {
        int u = q.front(); q.pop();
        result.push_back(u);
        for (int v : adjList[u]) {
            if (--inDegree[v] == 0) q.push(v);
        }
    }
    return result.size() == V ? result : vector<int>(); // 检查环
}

关键考点总结

  1. 基础概念:图的分类、术语(度、连通分量等)。
  2. 存储与遍历:邻接表/矩阵的选择,DFS/BFS的应用场景。
  3. 算法实现:Dijkstra、Floyd、Kruskal、Prim的代码模板。
  4. 拓扑排序:DAG的判定与排序方法。
  5. 复杂度分析:各算法的时间/空间复杂度比较。

建议结合实际问题(如LeetCode、OJ题目)练习代码实现。

相关推荐
贾斯汀玛尔斯3 小时前
每天学一个算法--拓扑排序(Topological Sort)
算法·深度优先
t***5443 小时前
如何配置Orwell Dev-C++使用Clang
开发语言·c++
CoderCodingNo3 小时前
【信奥业余科普】C++ 的奇妙之旅 | 13:为什么 0.1+0.2≠0.3?——解密“爆int”溢出与浮点数精度的底层原理
开发语言·c++
极客智造5 小时前
深入详解 C++ 智能指针:RAII 原理、分类特性、底层机制与工程实战
c++·智能指针
王璐WL6 小时前
【C++】类的默认成员函数(上)
c++
王老师青少年编程6 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【区间贪心】:区间覆盖(加强版)
c++·算法·贪心·csp·信奥赛·区间贪心·区间覆盖(加强版)
宏笋6 小时前
C++11完美转发的作用和用法
c++
格发许可优化管理系统6 小时前
MathCAD许可类型全面解析:选择最适合您的许可证
c++
旖-旎7 小时前
深搜(二叉树的所有路径)(6)
c++·算法·leetcode·深度优先·递归
GIS阵地7 小时前
QGIS的分类渲染核心类解析
c++·qgis·开源gis