# 集美大学课程实验报告-实验5:图
集美大学课程实验报告-实验5:图
| 项目名称 | 内容 |
|---|---|
| 课程名称 | 数据结构 |
| 班级 | 网安2413 |
| 指导教师 | 郑如滨 |
| 学生姓名 | 许晴 |
| 学号 | 202421336069 |
| 实验项目名称 | |
| 上机实践日期 | |
| 上机实践时间 | 2学时 |
一、目的(本次实验所涉及并要求掌握的知识点)
- 学会创建图(邻接矩阵),掌握在图上的基本操作。
- 掌握图遍历算法:DFS与BFS。
- 掌握编写最小生成树算法。
二、实验内容与设计思想
题目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开始 ),在构建邻接矩阵和检查颜色时出现逻辑错误。
- 解决方法:通过修正编号转换逻辑,在读取输入时正确适配数组索引解决。
实验体会和收获:
-实践中,我深入理解了DFS和BFS算法原理及在不同存储结构下的特性,将理论知识转化为实际应用。编程过程中,通过解决栈/队列操作错误、递归深度过深等问题,大幅提升了调试与代码优化能力。
六、附件(参考文献和相关资料)
以下请根据实际情况编写

浙公网安备 33010602011771号