集美大学课程实验报告-实验5-图
集美大学课程实验报告-实验5-图
项目名称 | 内容 |
---|---|
课程名称 | 数据结构 |
班级 | 网安2413 |
指导教师 | 郑如滨 |
学生姓名 | 林沁茹 |
学号 | 202421336067 |
实验项目名称 | 实验5-图 |
上机实践日期 | |
上机实践时间 | 2学时 |
一、目的(本次实验所涉及并要求掌握的知识点)
以下内容请根据实际情况编写
- 掌握memset的使用
- 掌握prim算法
- 掌握queue用法
二、实验内容与设计思想
题目1—图的创建
函数相关伪代码
图的创建
1.const int INF = 0x3f3f3f3f;
2.int a1[100][100];
3.map<char, int>a;
4.graph函数的创建
cin >> n >> m;
//vector<vector<int>>a1(n,vector<int>(n));(可以代替memset的初始化)
for (i = 0;i < n;i++)
|cin >> name;
|a[name] = i;
end
memset(a1, INF, sizeof(a1));//初始化
for (int i = 0; i < n; i++)
|a1[i][i] = 0;
end
for (i = 0;i < m;i++)
|cin >> x >> y >> z;
|a1[a[x]][a[y]] = z;
|a1[a[y]][a[x]] = z;
end
5.主函数
graph();
n = a.size();
for (i = 0; i < n; i++) {
|for (j = 0; j < n; j++) {
||if (a1[i][j] == INF) {
|||cout << "-1 ";
||else
|||cout << a1[i][j] << " ";
|cout << endl;
函数代码
#include<iostream>
#include <map>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
int a1[100][100];
map<char, int>a;
void graph() {
int n, m, i, z;
char x, y, name;
cout << "请输入图的顶点个数和边数" << endl;
cin >> n >> m;
//vector<vector<int>>a1(n,vector<int>(n));
cout << "请输入图的顶点名称" << endl;
for (i = 0;i < n;i++) {
cin >> name;
a[name] = i;
}
memset(a1, INF, sizeof(a1));
for (int i = 0; i < n; i++) {
a1[i][i] = 0;
}
cout << "请输入边的信息(起点 终点 权重): " << endl;
for (i = 0;i < m;i++) {
cin >> x >> y >> z;
a1[a[x]][a[y]] = z;
a1[a[y]][a[x]] = z;
}
}
int main()
{
graph();
int n, i, j;
n = a.size();
cout << "邻接矩阵如下:" << endl;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (a1[i][j] == INF) {
cout << "-1 ";
}
else {
cout << a1[i][j] << " ";
}
}
cout << endl;
}
return 0;
}
时间复杂度O(n^2),空间复杂度O(n^2)
题目2:图的遍历
函数相关伪代码
1.const int INF = 0x3f3f3f3f;
2.int a1[100][100];
3.map<char, int>a;
4.map<int, char>b;
5.bool visited[100];
6.graph函数
cin >> n >> m;
//vector<vector<int>>a1(n,vector<int>(n));
for (i = 0;i < n;i++)
|cin >> name;
|a[name] = i;
|b[i] = name;
end
memset(a1, INF, sizeof(a1));
for (int i = 0; i < n; i++)
|a1[i][i] = 0;
end
for (i = 0;i < m;i++) {
|cin >> x >> y >> z;
|a1[a[x]][a[y]] = z;
|a1[a[y]][a[x]] = z;
end
7.dfs算法
char c = b[x];
cout << c;
visited[x] = true;
for (int i = 0; i < a.size(); i++)
|if (a1[x][i] != INF&&!visited[i])
||dfs(i);
end
8.bfs算法
queue<int> queue;
queue.push(x);
visited[x] = true;
while (!queue.empty())
|u = queue.front();
|char c = b[u];
|cout << c;
|queue.pop();
|for (int i = 0; i < a.size(); i++) {
||if (a1[u][i] != INF && !visited[i]) {
|||queue.push(i);
|||visited[i] = true;
9.主函数
graph();
memset(visited, false, sizeof(visited));
x = a['a'];
dfs(x);
memset(visited, false, sizeof(visited));
y = a['f'];
dfs(y);
cout << endl;
memset(visited, false, sizeof(visited));
bfs(y);
函数代码
#include<iostream>
#include <map>
#include <cstring>
#include<queue>
using namespace std;
const int INF = 0x3f3f3f3f;
int a1[100][100];
map<char, int>a;
map<int, char>b;
bool visited[100];
void graph() {
int n, m, i, z;
char x, y, name;
cout << "请输入图的顶点个数和边数" << endl;
cin >> n >> m;
//vector<vector<int>>a1(n,vector<int>(n));
cout << "请输入图的顶点名称" << endl;
for (i = 0;i < n;i++) {
cin >> name;
a[name] = i;
b[i] = name;
}
memset(a1, INF, sizeof(a1));
for (int i = 0; i < n; i++) {
a1[i][i] = 0;
}
cout << "请输入边的信息(起点 终点 权重): " << endl;
for (i = 0;i < m;i++) {
cin >> x >> y >> z;
a1[a[x]][a[y]] = z;
a1[a[y]][a[x]] = z;
}
}
void dfs(int x) {
char c = b[x];
cout << c;
visited[x] = true;
for (int i = 0; i < a.size(); i++) {
if (a1[x][i] != INF&&!visited[i]) {
dfs(i);
}
}
}
void bfs(int x) {
queue<int> queue;
int u;
queue.push(x);
visited[x] = true;
while (!queue.empty()) {
u = queue.front();
char c = b[u];
cout << c;
queue.pop();
for (int i = 0; i < a.size(); i++) {
if (a1[u][i] != INF && !visited[i]) {
queue.push(i);
visited[i] = true;
}
}
}
}
int main()
{
int x,y;
graph();
memset(visited, false, sizeof(visited));
cout << "从a点开始深度优先遍历的结果是:";
x = a['a'];
dfs(x);
memset(visited, false, sizeof(visited));
cout << endl<<"从f点开始深度优先遍历的结果是:";
y = a['f'];
dfs(y);
cout << endl;
memset(visited, false, sizeof(visited));
cout << "从f点开始广度优先遍历的结果是:";
bfs(y);
return 0;
}
时间复杂度O(n^2 + m),空间复杂度O(n^2)
题目3:图着色问题
函数相关伪代码
1.search函数
for (i = 0;i < a.size();i++)
|for (j = 0;j < a[i].size();j++)
||m=a[i][j];
||if (a1[i] == a1[m])
|||return false;
end
for (i=0;i<a1.size();i++)
|for(j=0;j<i;j++)
||if(a1[i]==a1[j])
|||break;
|end
|if(i==j)
||c++;
end
if (c!= k)
|return false;
end
return true;
2.主函数
cin >> v >> e >> k;
vector<vector<int>>a(v);
vector<int>a1;
for (i = 0;i < e;i++) {
|cin >> s >> d;
|a[s-1].push_back(d-1);
|a[d - 1].push_back(s-1);
end
cin >> n;
for (i = 0;i < n;i++) {
|vector<int>a1(v);
|for (j = 0;j < v;j++) {
||cin >> s;
||a1[j]=s;
|end
|if (search(a, a1,k)) {
||cout << "Yes"<<endl;
|else
||cout << "No"<<endl;
end
函数代码
#include<iostream>
#include<vector>
using namespace std;
bool search(vector<vector<int>>& a, vector<int>& a1,int k) {
int i,j,m,c=0;
for (i = 0;i < a.size();i++) {
for (j = 0;j < a[i].size();j++) {
m=a[i][j];
if (a1[i] == a1[m]) {
return false;
}
}
}
for (i=0;i<a1.size();i++) {
for(j=0;j<i;j++){
if(a1[i]==a1[j]){
break;
}
}
if(i==j){
c++;
}
}
if (c!= k) {
return false;
}
return true;
}
int main()
{
int v, e, k, i, s, d, n,j;
cin >> v >> e >> k;
vector<vector<int>>a(v);
vector<int>a1;
for (i = 0;i < e;i++) {
cin >> s >> d;
a[s-1].push_back(d-1);
a[d - 1].push_back(s-1);
}
cin >> n;
for (i = 0;i < n;i++) {
vector<int>a1(v);
for (j = 0;j < v;j++) {
cin >> s;
a1[j]=s;
}
if (search(a, a1,k)) {
cout << "Yes"<<endl;
}
else {
cout << "No"<<endl;
}
}
return 0;
}
时间复杂度O(n^2),空间复杂度O(n^2)
题目4:公路村村通(最小生成树)
函数相关伪代码
1.const int INF = 0x3f3f3f3f;
2.prim函数算法
vector<int> p(n,INF);
vector<int>d(n,0);
p[0] = 0;
for (i = 0;i < n;i++)
|x = INF;
|k = -1;
|for (m = 0;m < n;m++)
||if (d[m] == 0 && p[m] < x)
|||x = p[m];
|||k = m;
|if (x == INF)
||return -1;
|d[k] = 1;
|sum += x;
|for (m = 0;m < n;m++)
||if (d[m]==0&&a[k][m] < p[m])
|||p[m] = a[k][m];
end
return sum;
3.主函数
cin >> n >> m;
vector<vector<int>> a(n, vector<int>(n, INF));
for (i = 0; i < m; i++)
|cin >> x >> y >> z;
|a[x - 1][y - 1] = z;
|a[y - 1][x - 1] = z;
end
int result = prim(a, n);
cout << result << endl;
函数代码
#include <iostream>
#include <vector>
using namespace std;
const int INF = 0x3f3f3f3f;
int prim(vector<vector<int>>& a, int n) {
vector<int> p(n,INF);
vector<int>d(n,0);
int i,sum=0,x,m,k;
p[0] = 0;
for (i = 0;i < n;i++) {
x = INF;
k = -1;
for (m = 0;m < n;m++) {
if (d[m] == 0 && p[m] < x) {
x = p[m];
k = m;
}
}
if (x == INF) {
return -1;
}
d[k] = 1;
sum += x;
for (m = 0;m < n;m++) {
if (d[m]==0&&a[k][m] < p[m]) {
p[m] = a[k][m];
}
}
}
return sum;
}
int main() {
int n, m, i, x, y, z;
cin >> n >> m;
vector<vector<int>> a(n, vector<int>(n, INF));
for (i = 0; i < m; i++) {
cin >> x >> y >> z;
a[x - 1][y - 1] = z;
a[y - 1][x - 1] = z;
}
int result = prim(a, n);
cout << result << endl;
return 0;
}
时间复杂度O(n^2),空间复杂度O(n^2)
三、实验使用环境(本次实验所使用的平台和相关软件)
以下请根据实际情况编写
- 操作系统:Windows 11专业版
- 编程语言:C++
- 开发工具:[Visual Studio 2022(https://code.visualstudio.com/)
四、实验步骤和调试过程(实验步骤、测试数据设计、测试结果分析)
以下请根据实际情况编写
题目1:图的创建
本机运行截图
PTA提交截图
![PTA提交截图]无
题目2:图的遍历
本机运行截图
PTA提交截图
![PTA提交截图]无
题目3:图着色问题
本机运行截图
![本机截图]
PTA提交截图
题目4:公路村村通(最小生成树)
本机运行截图
![本机截图]
PTA提交截图
五、实验小结(实验中遇到的问题及解决过程、实验体会和收获)
以下请根据实际情况编写
遇到的问题及解决方法:
- 问题:prim算法有问题
- 解决方法:修改代码
实验体会和收获:
- 学会了prim算法和memset的初始化
- 掌握了图的创建