实验8 图的操作

0x01 实验目的

掌握无向图的创建、遍历方法。

0x02 实验内容

  1. 创建图类,存储结构使用邻接矩阵。
  2. 输入图的节点数n(小于10个)、边数m,节点分别用1-n代表。
  3. 采用“起始节点,终止节点,权值”输入图的m条边,创建图。
  4. 输出从节点1开始的BFS广度遍历,在遍历过程中,如果从一个节点出发有多个可以选择的节点,则优先选择编号较小的节点。
  5. 输出从节点1开始的DFS深度遍历,在遍历过程中,如果从一个节点出发有多个可以选择的节点,则优先选择编号较小的节点。
  6. 输出从第1节点到最后一个节点(即第n个节点)最短路径的长度,如果没有路经,输出0。

0x03 实验过程分析

建立Class-graph

  • node:点数
  • edge:边数
  • noEdge:无边的标识
  • a:二维数组(指针形式的创建过程)二维数组的值代表权重
class graph {public:graph(int n, int e) {node = n;edge = e;a = new int *[n+1];for(int i = 1; i <= n; i++) {a[i] = new int[n+1];for(int j = 1; j <= n; j++) {a[i][j] = noEdge;}}}private:int node;int edge;int ** a;int noEdge = 0;
};

插入边操作

因为是无向图,所以边是相互的。

        void insertEdge(int start, int end, int weight) {a[start][end] = weight;a[end][start] = weight;}

广度优先搜索

用队列,因为要求输出逗号,所以写的比较复杂。

		void BFS(int v, int reach[], int label) {bool flag = false;queue<int> q;reach[v] = label;q.push(v);while(!q.empty()) {int w = q.front();q.pop();if(flag == false) {flag = true;cout<<w;} else cout<<","<<w;for(int i = 1; i <= node; i++) {if(a[w][i] != 0 && reach[i] != label) {q.push(i);reach[i] = label;}}}}

简化后:无输出。

  • v:搜索的起点
  • reach:存储该点是否到达过
  • label:到达后的标记
		void BFS(int v, int reach[], int label) {queue<int> q;reach[v] = label;q.push(v);while(!q.empty()) {int w = q.front();q.pop();for(int i = 1; i <= node; i++) {//当有这条边&没到达过才会将其入队if(a[w][i] != 0 && reach[i] != label) {q.push(i);reach[i] = label;}}}}

深度优先搜索

用堆栈,递归调用的思想。

		void DFS(int v, int reach[], int label) {reach[v] = label;if(fl == false) {cout<<v;fl = true;} else {cout<<","<<v;}for(int i = 1; i <= node; i++) {if(a[v][i] != 0 && reach[i] != label) {DFS(i,reach,label);}}}

同样,简化后代码:

  • v:搜索的起点
  • reach:存储该点是否到达过
  • label:到达后的标记

因为要求从小的数开始输出,所以没有“恢复”

		void DFS(int v, int reach[], int label) {reach[v] = label;for(int i = 1; i <= node; i++) {if(a[v][i] != 0 && reach[i] != label) {DFS(i,reach,label);}}}

加上“恢复”:

void DFS(int v, int reach[], int label) {reach[v] = label;for(int i = 1; i <= node; i++) {if(a[v][i] != 0 && reach[i] != label) {DFS(i,reach,label);reach[i] = 0;}}}

最短路径(起点到终点)

我的思路是:

  1. 首先,用宽度优先搜索,判断是否能够到达终点(看是否被到达标记标记到),不能的话,直接return 0;
  2. 然后,用深度优先搜索(必须用带“恢复”的因为此时我们要遍历全部的路径,求他们的权重比较,而不只是遵循该规则的路径 – 如果从一个节点出发有多个可以选择的节点,则优先选择编号较小的节点),寻找每一条从起点到终点的路径,然后比较它们的权重,取最小值,最后返回。
int pathLength(int start) {int reach[100] = {0};int rea[100] = {0};bfs(1,reach,2);if(reach[node] != 2) return 0;else {dfs(1,rea,2,0);return crr[0];}}void dfs(int v, int reach[], int label, int weight) {reach[1] = label;for(int i = 1; i <= node; i++) {if(a[v][i] != 0 && reach[i] != label) {weight += a[v][i];//到达终点就退出if(i == node) {//与之前的权重比较,小就保留,大就舍弃if(weight < crr[0]) crr[0] = weight;return;} else {reach[i] = label;dfs(i,reach,label,weight);reach[i] = 0;//一定要减掉,不仅要恢复标记,还要恢复权重,否则结果会偏大weight -= a[v][i];}}}}void bfs(int v, int reach[], int label) {queue<int> q;reach[v] = label;q.push(v);while(!q.empty()) {int w = q.front();q.pop();for(int i = 1; i <= node; i++) {if(a[w][i] != 0 && reach[i] != label) {q.push(i);reach[i] = label;}}}}

输入处理

输入全都是字符串,属实是绷不住了,处理麻烦死了
直接看下面完整代码叭。。

在这贴一组测试数据

输入
5,8
1,2,10
1,3,50
1,5,100
2,3,200
2,4,30
3,4,290
3,5,250
4,5,280
输出
12354
12345
100

0x04 完整代码

#include<bits/stdc++.h>
using namespace std;
const int M = 100;
int arr[M];
int brr[M];
int crr[M];
int path[M];
bool fl = false;
class graph {public:graph(int n, int e) {node = n;edge = e;a = new int *[n+1];for(int i = 1; i <= n; i++) {a[i] = new int[n+1];for(int j = 1; j <= n; j++) {a[i][j] = noEdge;}}}void insertEdge(int start, int end, int weight) {a[start][end] = weight;a[end][start] = weight;}void BFS(int v, int reach[], int label) {bool flag = false;queue<int> q;reach[v] = label;q.push(v);while(!q.empty()) {int w = q.front();q.pop();if(flag == false) {flag = true;cout<<w;} else cout<<","<<w;for(int i = 1; i <= node; i++) {if(a[w][i] != 0 && reach[i] != label) {q.push(i);reach[i] = label;}}}}void DFS(int v, int reach[], int label) {reach[v] = label;if(fl == false) {cout<<v;fl = true;} else {cout<<","<<v;}for(int i = 1; i <= node; i++) {if(a[v][i] != 0 && reach[i] != label) {DFS(i,reach,label);}}}int pathLength(int start) {int reach[100] = {0};int rea[100] = {0};bfs(1,reach,2);if(reach[node] != 2) return 0;else {dfs(1,rea,2,0);return crr[0];}}void dfs(int v, int reach[], int label, int weight) {reach[1] = label;for(int i = 1; i <= node; i++) {if(a[v][i] != 0 && reach[i] != label) {weight += a[v][i];if(i == node) {if(weight < crr[0]) crr[0] = weight;return;} else {reach[i] = label;dfs(i,reach,label,weight);reach[i] = 0;weight -= a[v][i];}}}}void bfs(int v, int reach[], int label) {queue<int> q;reach[v] = label;q.push(v);while(!q.empty()) {int w = q.front();q.pop();for(int i = 1; i <= node; i++) {if(a[w][i] != 0 && reach[i] != label) {q.push(i);reach[i] = label;}}}}private:int node;int edge;int ** a;int noEdge = 0;
};
int main() {cout<<"Input"<<endl;string n = "",m = "";string S;cin>>S;int temp;for(int i = 0; i < S.length(); i++) {if(S.at(i) == ',') {temp = i;break;}}for(int p = 0; p < temp; p++) {n += S.at(p);}for(int p = temp + 1; p < S.length(); p++) {m += S.at(p);}int num1 = stoi(n);int num2 = stoi(m); graph g(num1,num2);for(int i = 0; i < num2; i++) {string s;cin>>s;int fir = 0;int sec = 0;for(int j = 0; j < s.length(); j++) {if(s.at(j) == ',' && fir == 0) fir = j;else if(s.at(j) == ',' && fir != 0) {sec = j;break;}}string s1 = "";string s2 = "";string s3 = "";for(int p = 0; p < fir; p++) {s1 += s.at(p);}for(int q = fir + 1; q < sec; q++) {s2 += s.at(q);}for(int o = sec + 1; o < s.length(); o++) {s3 += s.at(o);}g.insertEdge(stoi(s1), stoi(s2), stoi(s3));}cout<<"Output"<<endl;g.BFS(1,arr,2);cout<<endl;g.DFS(1,brr,2);cout<<endl;//让第0组权重无限大,其他就都会比他小了(crr[0] = 10000000;int ans = g.pathLength(1);cout<<ans<<endl;cout<<"End";return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/192047.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XIAO ESP32S3之SenseCraft 模型助手部署

sipeed教程&#xff1a;SenseCraft 模型助手部署 | Seeed Studio Wiki 一、安装ESP-IDF 鉴于我的电脑之前安装过esp-idf v4.3版本&#xff0c;而ESP32-S3需要v4.4及以上版本才支持&#xff0c;所以将esp-idf更新到最新5.1版本。 1、启动mingw32.exe应用 2、进入esp-idf目录 …

重要通知丨 JumpServer 开源堡垒机 V2 社区版即将停止维护

尊敬的 JumpServer 开源堡垒机用户&#xff0c;您好&#xff01; 根据《关于 JumpServer 开源堡垒机 V2 版本产品生命周期的相关说明》&#xff0c;JumpServer 开源堡垒机 V2 版本&#xff08;社区版&#xff09;将于 2023 年 12 月 31 日停止维护支持。 在过去的两年多时间里…

跟着GPT学习shell脚本,理论与实践相结合的学习计划。

学习计划&#xff1a;初学者到高手 第1-2周&#xff1a;基础入门 目标&#xff1a;了解Shell脚本的基本概念&#xff0c;掌握基础命令。内容&#xff1a; Shell脚本是什么&#xff0c;为什么使用Shell脚本。基本的Shell命令&#xff08;如ls, cd, mkdir, rm等&#xff09;。简…

封装hook函数【便于复用】

目录 一般函数封装封装hook函数 一般函数封装 普通的删除逻辑封装函数—子组件点击删除-通过 defineEmits 通知父组件&#xff08;自定义事件&#xff09;进行删除 const deleteLoading ref(false) const emits defineEmits<{(e: click-delete, id: string): void }>()…

二叉树的层序遍历(广度搜索法) Python

思路&#xff1a; 层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树 需要借用一个辅助数据结构即队列来实现&#xff0c;队列先进先出&#xff0c;符合一层一层遍历的逻辑&#xff0c;而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。 而这种层序遍历方式就是…

ELK配置记录

1. filebeat.yml配置 启动命令&#xff1a; ./filebeat -e -c filebeat.yml # 输入 filebeat.inputs: - type: logenabled: truepaths:- /soft/log/base.*#跨行日志正则&#xff0c;从有时间的开始&#xff0c;到下一个时间之前结束multiline.pattern: ^\[[0-9]{4}-[0-9]{2}…

Python数据类型字典分析

文章目录 1. 创建字典1.1 创建空字典1.2 创建非空字典 2. 新增字典元素2.1 thisdict[new_key] new_value2.2 update 方法 3. 删除字典元素4. 查找字典元素4.1 in 和 in not 操作符4.2 get 方法4.3 thisdict[key] 5. 修改字典元素6. 遍历字典元素6.1 for 循环遍历6.2 keys 方法…

使用纯js码2个实用功能banner图标切换和表格制作

“I can accept failure, but I cant acceptnot trying.”—— by Michael Jordan    “我可以接受失败&#xff0c;但我不能接受放弃。” ——迈克尔•乔丹   banner图标切换 js原生&#xff1a;图片地址你们自己设置位置&#xff0c;相对位置或者绝对位置即可 <!DOCTY…

【CTA认证】Android8实现android6以下的应用运行时也要申请权限

需求 CTA入网认证&#xff0c;要求低版本比如Android6以下的应用&#xff0c;运行时&#xff0c;也需要有运行时权限(Runtime Permission)功能&#xff0c;不能默认就取到权限&#xff0c;必须人工在设置中打开才可。 环境 Android 8 实现 frameworks 修改思路是所有APP都…

蓝桥杯物联网竞赛_STM32L071_6_RTC显示

作用&#xff1a; RTC在STM32微控制器中通常由一个独立的低功耗晶振和相关的寄存器组成。它可以独立于主处理器运行&#xff0c;即使在系统电源关闭的情况下(需要备用纽扣电池)&#xff0c;也能继续计时和记录日期。注意&#xff1a;RTC是芯片内部的功能&#xff0c;并没有和G…

Android跨进程通信,RPC,IPC

文章目录 Android跨进程通信&#xff0c;RPC&#xff0c;IPC1.IPC原理2.RPC原理2.RPC原理 Android跨进程通信&#xff0c;RPC&#xff0c;IPC RPC&#xff08;基于IPC实现&#xff09; Android binder就是一个RPC框架&#xff0c;在已经启动的一个进程a中&#xff0c;访问到进…

Eaxyx 让圆球跟随鼠标移动

如果出现2023&#xff0c;代表配置成功: 进入Eaxy官方网站&#xff0c;点击文档&#xff1a; 选择 函数->绘图函数->initgraph: 可以看见initgraph&#xff08;&#xff09;函数有如下三个参数: 现在我们想生成一个1280*720大小的窗口&#xff1a; 我们需写如下代码: 但…

AIGC: 关于ChatGPT中的核心API调用示例

Open AI 的 api 调用示例 API的调用的文档&#xff1a;https://platform.openai.com/docs/api-reference/introductionChatGPT官方提供了 Python版的包 和 Nodejs版的包 $pip install openai$npm install openai 我们使用 python3.8版本来安装: $sudo python3.8 -m pip instal…

数据结构算法-冒泡排序算法

引言 虽然选择排序好用 &#xff0c;但有点问题 也就是频繁找最大值下标 放到 未排序的后面 因为每次需要扫描整个未排序序列&#xff0c;找到最大值或最小值的下标&#xff0c;并将其交换到未排序序列的最后一个位置。这样做的问题在于&#xff0c;在后面的迭代中&#xff0c…

C# WPF上位机开发(计算器界面设计)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 c# wpf最大的优势就是开发业务软件比较快、效率比较高。一般来说&#xff0c;它的界面和逻辑部分可以同时开发。界面的部分用xaml编写即可&#xf…

Spring Framework详解

学习目标 能够说出Spring的体系结构 能够编写IOC入门案例 能够编写DI入门案例 能够配置setter方式注入属性值 能够配置构造方式注入属性值 能够理解什么是自动装配 一、Spring简介 1 Spring课程介绍 问题导入 我们为什么要学习Spring框架&#xff1f; 1.1 为什么要学 Spri…

Nat. Mach. Intell. | 预测人工智能的未来:在指数级增长的知识网络中使用基于机器学习的链接预测

今天为大家介绍的是来自Mario Krenn团队的一篇论文。一个能够通过从科学文献中获取洞见来建议新的个性化研究方向和想法的工具&#xff0c;可以加速科学的进步。一个可能受益于这种工具的领域是人工智能&#xff08;AI&#xff09;研究&#xff0c;近年来科学出版物的数量呈指数…

数据结构—两个有序单链表的合并排序算法

viod merge(LNode *A,LNode *B){ LNode *C;//新节点 LNode *p C;//辅助指针 while(A->next !null && B->next !null){ if(A->next->data > B->next->data){//A节点大 p->nextA->next;//A元素插入C AA>next; pp->next; }else{ p->…

如何选择适合的光电传感器与 STM32 微控制器进行接口设计

本文介绍了如何选择适合的光电传感器与 STM32 微控制器进行接口设计的方法。首先我们将介绍一些选择光电传感器的关键因素&#xff0c;包括测量范围、响应时间、分辨率和输出类型。然后我们将介绍如何根据所选传感器的特性进行硬件连接和接口设计。最后&#xff0c;我们将提供示…

机器学习在缺陷检测中的实际效果与应用案例

机器学习在缺陷检测中的实际效果与应用案例 机器学习在缺陷检测中的应用已经变得非常广泛&#xff0c;并且在许多行业中都得到了实践验证。通过使用机器学习算法&#xff0c;我们能够训练模型来自动检测产品或过程中的缺陷&#xff0c;从而提高生产效率&#xff0c;降低人工检…