集美大学课程实验报告-实验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)

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

以下请根据实际情况编写


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

以下请根据实际情况编写

题目1:图的创建

本机运行截图

PTA提交截图
![PTA提交截图]无

题目2:图的遍历

本机运行截图

PTA提交截图
![PTA提交截图]无

题目3:图着色问题

本机运行截图
![本机截图]

PTA提交截图

题目4:公路村村通(最小生成树)

本机运行截图
![本机截图]

PTA提交截图


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

以下请根据实际情况编写

遇到的问题及解决方法:

  1. 问题:prim算法有问题
  • 解决方法:修改代码

实验体会和收获:

  • 学会了prim算法和memset的初始化
  • 掌握了图的创建

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

posted @ 2025-05-11 22:06  穗和  阅读(22)  评论(0)    收藏  举报