# 集美大学课程实验报告-实验5:图

集美大学课程实验报告-实验5:图

项目名称 内容
课程名称 数据结构
班级 网安2413
指导教师 郑如滨
学生姓名 许晴
学号 202421336069
实验项目名称
上机实践日期
上机实践时间 2学时

一、目的(本次实验所涉及并要求掌握的知识点)

  1. 学会创建图(邻接矩阵),掌握在图上的基本操作。
  2. 掌握图遍历算法:DFS与BFS。
  3. 掌握编写最小生成树算法。

二、实验内容与设计思想

题目1:图的创建

函数代码

#include <iostream>
#include <cstring>

using namespace std;

// 定义图的结构
const int MAX_VERTEX = 100;
typedef char VexType;
struct MyGraph {
    VexType vexs[MAX_VERTEX];  
    int arcs[MAX_VERTEX][MAX_VERTEX]; 
    int vexnum; 
    int arcnum;  
};

// 创建无向图(按照给定格式输入)
void CreateUDGraphFromConsole(MyGraph& G) {
    cin >> G.vexnum >> G.arcnum;
    for (int i = 0; i < G.vexnum; i++) {
        cin >> G.vexs[i];
    }
    memset(G.arcs, 0, sizeof(G.arcs));
    for (int i = 0; i < G.arcnum; i++) {
        VexType v1, v2;
        int weight;  // 这里虽然权重都为1,但按格式读取
        cin >> v1 >> v2 >> weight;
        int index1 = -1, index2 = -1;
        for (int j = 0; j < G.vexnum; j++) {
            if (G.vexs[j] == v1) {
                index1 = j;
            }
            if (G.vexs[j] == v2) {
                index2 = j;
            }
        }
        if (index1 != -1 && index2 != -1) {
            G.arcs[index1][index2] = 1;
            G.arcs[index2][index1] = 1;
        }
    }
}

题目2:图的遍历

函数代码

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

// 定义图的结构
const int MAX_VERTEX = 100;
typedef char VexType;
struct MyGraph {
    VexType vexs[MAX_VERTEX];  // 顶点数组
    int arcs[MAX_VERTEX][MAX_VERTEX];  // 邻接矩阵
    int vexnum;  // 顶点数
    int arcnum;  // 边数
};

// 创建无向图(按照给定格式输入)
void CreateUDGraphFromConsole(MyGraph& G) {
    cin >> G.vexnum >> G.arcnum;
    for (int i = 0; i < G.vexnum; i++) {
        cin >> G.vexs[i];
    }
    memset(G.arcs, 0, sizeof(G.arcs));
    for (int i = 0; i < G.arcnum; i++) {
        VexType v1, v2;
        int weight;  // 此处权重虽都为1,但按格式读取
        cin >> v1 >> v2 >> weight;
        int index1 = -1, index2 = -1;
        for (int j = 0; j < G.vexnum; j++) {
            if (G.vexs[j] == v1) {
                index1 = j;
            }
            if (G.vexs[j] == v2) {
                index2 = j;
            }
        }
        if (index1 != -1 && index2 != -1) {
            G.arcs[index1][index2] = 1;
            G.arcs[index2][index1] = 1;
        }
    }
}

// 深度优先搜索
void DFS(MyGraph G, int v, bool visited[]) {
    visited[v] = true;
    cout << G.vexs[v];
    for (int i = 0; i < G.vexnum; i++) {
        if (G.arcs[v][i] == 1 &&!visited[i]) {
            DFS(G, i, visited);
        }
    }
}

// 广度优先搜索
void BFS(MyGraph G, int v, bool visited[]) {
    queue<int> q;
    visited[v] = true;
    q.push(v);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        cout << G.vexs[u];
        for (int i = 0; i < G.vexnum; i++) {
            if (G.arcs[u][i] == 1 &&!visited[i]) {
                visited[i] = true;
                q.push(i);
            }
        }
    }
}

int main() {
    MyGraph G;
    CreateUDGraphFromConsole(G);

    bool visited[MAX_VERTEX];

    // 从A节点进行DFS
    memset(visited, false, sizeof(visited));
    int aIndex = -1;
    for (int i = 0; i < G.vexnum; i++) {
        if (G.vexs[i] == 'a') {
            aIndex = i;
            break;
        }
    }
    if (aIndex != -1) {
        cout << "从A节点进行DFS遍历结果: ";
        DFS(G, aIndex, visited);
        cout << endl;
    }

    // 从F节点进行DFS
    memset(visited, false, sizeof(visited));
    int fIndex = -1;
    for (int i = 0; i < G.vexnum; i++) {
        if (G.vexs[i] == 'f') {
            fIndex = i;
            break;
        }
    }
    if (fIndex != -1) {
        cout << "从F节点进行DFS遍历结果: ";
        DFS(G, fIndex, visited);
        cout << endl;
    }

    // 从F节点进行BFS
    memset(visited, false, sizeof(visited));
    if (fIndex != -1) {
        cout << "从F节点进行BFS遍历结果: ";
        BFS(G, fIndex, visited);
        cout << endl;
    }

    return 0;
}

题目3:PTA:着色问题

函数代码

#include <iostream>
#include <vector>
#include <unordered_set>

using namespace std;

int main() {
    int V, E, K;
    cin >> V >> E >> K;
    vector<vector<int>> adj(V + 1);
    for (int i = 0; i < E; ++i) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    int N;
    cin >> N;
    while (N--) {
        vector<int> colors(V);
        unordered_set<int> color_set;
        for (int i = 0; i < V; ++i) {
            cin >> colors[i];
            color_set.insert(colors[i]);
        }
        if (color_set.size() != K) {
            cout << "No" << endl;
            continue;
        }
        bool valid = true;
        for (int u = 1; u <= V; ++u) {
            for (int v : adj[u]) {
                if (colors[u - 1] == colors[v - 1]) {
                    valid = false;
                    break;
                }
            }
            if (!valid) break;
        }
        cout << (valid ? "Yes" : "No") << endl;
    }
    return 0;
}

题目4:PTA:公路村村通

函数代码

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct Edge {
    int u, v, cost;
    bool operator<(const Edge &other) const {
        return cost < other.cost;
    }
};

vector<int> parent;

int find(int u) {
    if (parent[u] != u)
        parent[u] = find(parent[u]);
    return parent[u];
}

void unite(int u, int v) {
    u = find(u);
    v = find(v);
    if (u != v)
        parent[v] = u;
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<Edge> edges(m);
    for (int i = 0; i < m; ++i) {
        cin >> edges[i].u >> edges[i].v >> edges[i].cost;
    }
    sort(edges.begin(), edges.end());
    parent.resize(n + 1);
    for (int i = 1; i <= n; ++i) {
        parent[i] = i;
    }
    int total_cost = 0;
    int edges_used = 0;
    for (const Edge &e : edges) {
        if (find(e.u) != find(e.v)) {
            unite(e.u, e.v);
            total_cost += e.cost;
            edges_used++;
            if (edges_used == n - 1)
                break;
        }
    }
    if (edges_used == n - 1) {
        cout << total_cost << endl;
    } else {
        cout << -1 << endl;
    }
    return 0;
}

三、实验使用环境(本次实验所使用的平台和相关软件)

  • 操作系统:Windows 11 professional
  • 编程语言:C++
  • 开发工具:[Visual Studio 2022]
  • 编译器:可选

四、实验步骤和调试过程(实验步骤、测试数据设计、测试结果分析)

题目1:图的创建

本机运行截图

题目2:图的遍历

本机运行截图

题目3:PTA:着色问题

本机运行截图

PTA提交截图

题目4:PTA:公路村村通

本机运行截图

PTA提交截图


五、实验小结(实验中遇到的问题及解决过程、实验体会和收获)

遇到的问题及解决方法:

  1. 问题:图着色问题,起初未严格按题目要求处理顶点和颜色编号(从1开始 ),在构建邻接矩阵和检查颜色时出现逻辑错误。
    • 解决方法:通过修正编号转换逻辑,在读取输入时正确适配数组索引解决。

实验体会和收获:

-实践中,我深入理解了DFS和BFS算法原理及在不同存储结构下的特性,将理论知识转化为实际应用。编程过程中,通过解决栈/队列操作错误、递归深度过深等问题,大幅提升了调试与代码优化能力。


六、附件(参考文献和相关资料)

以下请根据实际情况编写

  1. C++ Primer
  2. 相关博客文章
posted @ 2025-05-18 21:43  计算机糕手  阅读(71)  评论(0)    收藏  举报