实验报告5 - 图
集美大学课程实验报告-实验5:图
| 项目名称 | 内容 |
|---|---|
| 课程名称 | 数据结构 |
| 参与者 | 豆芽菜 |
| 实验项目名称 | 图 |
| 上机实践日期 | 2026.05.14 |
| 上机实践时间 | 2学时 |
一、目的(本次实验所涉及并要求掌握的知识点)
- 学习图的基本概念、遍历等基础操作。
- 掌握 图 的创建和修改操作。
- 理解图在实际问题中的应用。
二、实验内容与设计思想
任务一:图的创建
MyGraph的结构体
typedef int ArcCell;
typedef char VexType;
typedef struct
{
VexType vexs[MAX];//点集
ArcCell arcs[MAX];//边集
int n,e;
}MyGraph;
主要函数代码
//定位
int LocateVex(MyGraph* G,VexType value)
{
for(int i=0;i<G->n;i++)
{
if(value==G->vexs[i])
return i;
}
return -1;
}
void CreateGraph(MyGraph &G,int n,int e)
{
//1、初始化点集和边集
G.n=n;
G.e=e;
memset(G.vexs,0,sizeof(G.vexs));
memset(G.arcs,0,sizeof(G.arcs));
//2、初始化点列表
for(size_t i=0;i<G.n;i++)
{
cin>>G.vexs[i];
}
//初始化边矩阵
char x,y;
ArcCell value;
for(size_t i=0;i<G.e;i++)
{
cin>>x>>y>>value;
int x1=LocateVex(&G,x);
int y1=LocateVex(&G,y);
G.arcs[x1][y1]=value;
G.arcs[y1][x1]=value;
}
}
任务二:图的遍历(DFS/BFS)
DFS遍历
viod DFS(MyGraph* G,Vextype v,bool visited[])
{
//访问呢当前顶点
cout<<G->vexs[v];
visited[v]=true;
//遍历所有的顶点,找到未被访问的邻接点
for(int i=0;i<G->n;i++)
{
if(G->arcs[i]!=0&&!visited[i])
{
DFS(G,i,visited);//递归访问
}
}
}
viod DFSTravse(MyGraph* G)
{
bool visited[MAX];
//初始化,所有顶点均未被访问
for(int i=0;i<G->n;i++)
{
visited[i]=false;
}
for(int i=0;i<G->n;i++)
{
if(!visited[i])
{
DFS(G,i,visited);//递归访问
}
}
}
BFS遍历
void BFS(MyGraph* G,int v,bool visited[])
{
queue<int> q;
//访问当前顶点
cout<<G->vexs[v];
visited[v]=true;
q.push(v); //入队
while(!q.empty())
{
int front=q.front();
q.pop(); //队头出队
//遍历所有顶点,寻找邻接点
for(int i=0;i<G->n;i++)
{
//有边+未访问,访问并入队
if(G->arcs[front][i]!=0 && !visited[i])
{
cout<<G->vexs[i];
visited[i]=true;
q.push(i);
}
}
}
}
void BFSTraverse(MyGraph* G)
{
bool visited[MAX];
//标记初始化
for(int i=0;i<G->n;i++)
visited[i]=false;
for(int i=0;i<G->n;i++)
{
if(!visited[i])
BFS(G,i,visited);
}
}
pta着色问题
主要函数伪代码
【版本一】这个是先构建图然后再通过图的遍历,并判断相邻节点是否相等,
用flag=1/0来判断可以吧,图的构建也只要有储存n,e的两个数组和指向下一个节点的指针
【版本二(经过ai指点后)】 由于这个不用图结构,只要判断点的颜色和边的关系,
不用构建图的结构体,就用简单的一维数组储存顶点和顶点颜色,
二维数组储存边的两个端点,顺便用cnt计颜色是否超过k,超出范围也是不符合的
具体实现代码
#include<iostream>
#define MAXV 500
#define MAXE 125000 //不会超过n*(n-1)/2条边
using namespace std;
int edges[MAXE][2];
int main()
{
int v,e,k,n;
cin>>v>>e>>k;
for(int i=0;i<e;i++)
{
int u,w;
cin>>u>>w;
edges[i][0]=u;
edges[i][1]=w;
}
int color[MAXV+1];
cin>>n;
for(int j=0;j<n;j++)
{
bool flag=true;
for(int i=1;i<=v;i++)
{
cin>>color[i];
}
for(int m=0;m<e;m++)
{
int x=edges[m][0];
int y=edges[m][1];
if(color[x]==color[y])
{
flag=false;
break;
}
}
int used_color[501]={0};
int cnt=0;
for(int l=1;l<=v;l++)
{
if(!used_color[color[l]])
{
used_color[color[l]]=1;
cnt++;
}
}
if (cnt >k||cnt<k) {
flag=false;
}
if(flag){
cout << "Yes"<<endl;
}else
cout << "No"<<endl;
}
return 0;
}
ai结合题:公路村村通
给ai的伪代码
输入顶点数n,边数m
邻接矩阵初始化
for i从1到n:
for j从1到n:
G[i][j] =0;
for m次循环:
输入u, v, w
if w < G[u][v]:
G[u][v] = w
G[v][u] = w
visited初始化为未访问(0)
lowcost全部置为0
lowcost[起点1] = 0
sum = 0 // 最小生成树总权值
cnt = 0 // 已选顶点数量
每次选一个点加入生成树
for i从1到n:
// 1、选出不在树中、lowcost最小的顶点k
k = -1
min_val = 0;
for j从1到n:
如果visited[j]==0 且 lowcost[j]<min_val:
min_val = lowcost[j]
k = j
if k == -1: // 剩余点无法连通,退出
break
// 2、将k并入最小生成树
visited[k] = 1
sum = sum + min_val
cnt = cnt + 1
// 3、用k更新剩余点到生成树的最短距离lowcost
for j从1到n:
if visited[j]==0 且 G[k][j] < lowcost[j]:
lowcost[j] = G[k][j]
// 判断是否构成完整生成树
if cnt == n:
输出sum
else:
输出-1
ai实现代码
#include <stdio.h>
#include <string.h>
#define MAXN 1005
#define INF 0x3f3f3f3f
int G[MAXN][MAXN];
int lowcost[MAXN];
int visited[MAXN];
int main() {
int n, m;
scanf("%d%d", &n, &m);
// 初始化图
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
G[i][j] = INF;
for (int i = 0; i < m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
if (w < G[u][v]) { // 可能有多条边,取最小
G[u][v] = w;
G[v][u] = w;
}
}
memset(visited, 0, sizeof(visited));
memset(lowcost, 0x3f, sizeof(lowcost));
// 从1号点开始
lowcost[1] = 0;
int sum = 0, cnt = 0;
for (int i = 1; i <= n; i++) {
// 找离生成树最近的点
int k = -1, min = INF;
for (int j = 1; j <= n; j++) {
if (!visited[j] && lowcost[j] < min) {
min = lowcost[j];
k = j;
}
}
if (k == -1) break; // 不连通了
visited[k] = 1;
sum += min;
cnt++;
// 更新lowcost
for (int j = 1; j <= n; j++) {
if (!visited[j] && G[k][j] < lowcost[j]) {
lowcost[j] = G[k][j];
}
}
}
if (cnt == n)
printf("%d\n", sum);
else
printf("-1\n");
return 0;
}
三、实验使用环境(本次实验所使用的平台和相关软件)
- 操作系统:Windows 10 专业版
- 编程语言:C++
- 开发工具:Visual Studio 2022
- 编译器:vs2022默认编译器、pta
四、实验步骤和调试过程
任务一&任务二:图的创建和遍历
本机运行截图

着色问题:
pta提交截图

与ai的交流过程:
相关截图


五、实验小结(实验中遇到的问题及解决过程、实验体会和收获)
遇到的问题及解决方法:
- 问题:代码注释冗余,伪代码表意不够清楚。
- 解决方法:借助ai辅助优化出一个有条理逻辑的注释。
- 问题:着色问题漏了颜色总数cnt小于k的情况
- 问题:ai给的代码超出我的知识水平,且有较多逻辑跟不上它的解答
- 解决方法:把疑问喂给他,和他多沟通,实现知识的连接。
实验体会和收获:
- 掌握了图的创建、遍历和具体应用的基本操作。
- 学习关键字输入,与ai的沟通学习方式。
浙公网安备 33010602011771号