当前位置: 首页 > news >正文

hnust 1963: 邻接矩阵表示法

hnust 1963: 邻接矩阵表示法

题目描述
输入一个图,用邻接矩阵存储,并实现一些操作。
拷贝下面的代码,按要求完成其中的FirstAdjVex,NextAdjVex和CreateUDG操作,其他地方不得改动。

//邻接矩阵表示图
#include <iostream>
#include <iomanip>
#include <cstdio>
using namespace std;#define MVNum 100     //最大顶点数
typedef string VerTexType; //假设顶点的数据类型为字符串
typedef int ArcType;             //假设边的权值类型为整型//------------图的邻接矩阵------------------
typedef struct {VerTexType vexs[MVNum];            //顶点表ArcType arcs[MVNum][MVNum];      //邻接矩阵int vexnum, arcnum;                //图的当前点数和边数
} Graph;//得到顶点i的数据
VerTexType Vertexdata(const Graph &g, int i)
{return g.vexs[i];
}int LocateVex(const Graph &g, VerTexType v)
{//确定点v在G中的位置for(int i = 0; i < g.vexnum; ++i)if(g.vexs[i] == v)return i;return -1;
}//LocateVexint FirstAdjVex(const Graph &g, int v)
{//返回v的第一个邻接点编号,没有返回-1/****在此下面完成代码***************//***********************************/
}//FirstAdjVexint NextAdjVex(const Graph &g, int v, int w)
{//返回v相对于w的下一个邻接点,没有返回-1/****在此下面完成代码***************//***********************************/
}//NextAdjVexvoid CreateUDG(Graph &g)
{//采用邻接矩阵表示法,创建无向图G/****在此下面完成代码***************//***********************************/
}//CreateUDNvoid DestroyUDG(Graph &g)
{//you should do this
}//输出邻接矩阵
void PrintUDG(const Graph& g)
{int i, j;cout << "    ";for(i = 0; i < g.vexnum; i++) {cout << setw(4) << g.vexs[i] ;}cout << endl;for(i = 0; i < g.vexnum; i++) {cout << setw(4) << g.vexs[i];for(j = 0; j < g.vexnum; j++) {cout << setw(4) << g.arcs[i][j];}cout << endl;}
}int main()
{Graph g;CreateUDG(g);//输出各个顶点的邻接点for(int i = 0; i < g.vexnum; i++) {cout << Vertexdata(g, i) << ":";for(int w = FirstAdjVex(g, i); w >= 0; w = NextAdjVex(g, i, w)) {cout << ' ' << Vertexdata(g, w);}cout << endl;}PrintUDG(g);DestroyUDG(g);return 0;
}//main

输入
输入的第一行是两个整数,分别是图的总顶点数n和总边数e

第二行是n个空格分开的字符串,是顶点的名字,依次对应编号0~n-1。

随后有e行,每行两个空格分开的顶点名字,表示一条边的两个顶点。

具体见样例。

输出
首先输出n行,每行是第i个顶点的邻接顶点。

再输出该图的邻接矩阵。

具体见样例。

样例输入 Copy
8 9
v1 v2 v3 v4 v5 v6 v7 v8
v1 v2
v1 v3
v2 v4
v2 v5
v3 v6
v3 v7
v4 v8
v5 v8
v6 v7
样例输出 Copy
v1: v2 v3
v2: v1 v4 v5
v3: v1 v6 v7
v4: v2 v8
v5: v2 v8
v6: v3 v7
v7: v3 v6
v8: v4 v5v1  v2  v3  v4  v5  v6  v7  v8v1   0   1   1   0   0   0   0   0v2   1   0   0   1   1   0   0   0v3   1   0   0   0   0   1   1   0v4   0   1   0   0   0   0   0   1v5   0   1   0   0   0   0   0   1v6   0   0   1   0   0   0   1   0v7   0   0   1   0   0   1   0   0v8   0   0   0   1   1   0   0   0

提示
样例对应教材6.5的图G4

解题过程

数组(邻接矩阵)表示法
定义
图没有顺序存储结构,但可以借助二维数组来表示元素间的关系

在无向图的邻接矩阵中,它的特点:
无向图的邻接矩阵是对称的
顶点 i 的度 = 第 i 行/列 中 1 的个数

有向图的邻接矩阵
第 i 行含义:以节点 Vi 为尾的弧(即出度边)
第 i 列含义:以节点 Vi 为头的弧(即入度边)

在有向图的邻接矩阵中,它的特点:
有向图的邻接矩阵可能是不对称的
顶点的出度 = 第 i 行元素之和
顶点的入度 = 第 i 列元素之和
顶点的度 = 第 i 行元素之和 + 第 i 列元素之和
网(即有权图)的邻接矩阵表示法
定义为:A.arcs[i][j] = Wij 存在从 i 顶点到 j 顶点的弧或者边的权,否则 A.arcs[i][j] = 无穷大

邻接矩阵的优缺点
优点:
直观、简单、好理解
方便检查任意一对顶点间是否存在边
方便找任一顶点的所有邻接点(右边直接相连的顶点)
方便计算任一顶点的度(从该点发出的边数为出度,指向该点的边数为入度)
无向图:对应行(或列)非0元素的个数
有向图:对应行非0元素的个数是出度;对应列非0元素的个数是入度

缺点:
不便于增加和删除顶点
浪费空间-存稀疏图(点很多而边很少)有大量无效元素
对稠密图(特别是完全图)还是很合算的
浪费时间-统计稀疏图中一共有多少条边

这段C++代码实现了无向图的创建、遍历和销毁,使用了邻接矩阵来表示图。下面是对代码的详细解析:

1. 头文件和命名空间

  • 包含<bits/stdc++.h>,提供标准库支持。
  • 使用using namespace std;简化代码。

2. 宏定义和类型定义

  • MVNum定义了最大顶点数。
  • VerTexTypeArcType分别定义了顶点和边的数据类型。

3. 图结构定义

  • Graph结构体定义了图的邻接矩阵表示,包含顶点数组、邻接矩阵以及顶点数和边数。

4. 函数定义

  • LocateVex:查找顶点在图中的位置,如果找到则返回索引,否则返回-1。
  • FirstAdjVex:返回顶点的第一个邻接点的索引,如果没有邻接点则返回-1。
  • NextAdjVex:返回顶点相对于给定邻接点的下一个邻接点的索引,如果没有则返回-1。

5. 图的创建函数CreateUDG

  • 读取顶点数和边数。
  • 读取顶点信息并存储到顶点数组中。
  • 循环读取边的信息,使用LocateVex找到顶点的索引,并在邻接矩阵中相应位置设置边的信息。

6. 图的销毁函数DestroyUDG

  • 使用memset将邻接矩阵的所有元素设置为0,销毁图。

7. 图的输出函数PrintUDG

  • 输出图的邻接矩阵,格式化输出顶点和对应的邻接点。

8. 主函数main

  • 创建图g并调用CreateUDG函数。
  • 遍历所有顶点,输出每个顶点及其邻接点。
  • 调用PrintUDG函数输出整个图的邻接矩阵。
  • 调用DestroyUDG函数销毁图。

代码逻辑分析

  • 代码首先定义了图的数据结构和相关操作函数。
  • 使用CreateUDG函数根据用户输入创建图。
  • 使用FirstAdjVexNextAdjVex函数遍历每个顶点的邻接点。
  • 使用PrintUDG函数输出图的邻接矩阵,以便于观察。
  • 最后,使用DestroyUDG函数清理图占用的资源。

潜在问题

  • CreateUDG函数中,如果输入的边信息中顶点不在顶点数组中,程序将不会报错,但这些顶点不会在图中表示。
  • DestroyUDG函数中,只销毁了邻接矩阵的数据,没有销毁顶点数组。

改进建议

  • CreateUDG函数中添加对输入边的顶点是否存在的检查。
  • 考虑动态分配顶点数组和邻接矩阵的内存,并在DestroyUDG函数中释放这些内存。
  • 考虑添加更多图操作的函数,如搜索、路径查找等。
  • 考虑使用std::vector来代替固定大小的数组,以提高代码的灵活性和安全性。

部分代码

typedef struct
{VerTexType vexs[MVNum];            //顶点表,用以存储顶点ArcType arcs[MVNum][MVNum];      //邻接矩阵int vexnum, arcnum;                //图的当前点数和边数
} Graph;
int LocateVex(const Graph &g, VerTexType v)
{//确定点v在G中顶点表的位置for(int i = 0; i < g.vexnum; ++i)if(g.vexs[i] == v)return i;return -1;
}//LocateVex
int FirstAdjVex(const Graph &g, int v)
{//返回顶点v的第一个邻接点编号,没有返回-1/****在此下面完成代码***************/for(int i=0; i<g.vexnum; i++)if(g.arcs[v][i])return i;return -1;/***********************************/
}//FirstAdjVex
int NextAdjVex(const Graph &g, int v, int w)
{//返回顶点v相对于w的下一个邻接点,没有返回-1/****在此下面完成代码***************/for(int i=w+1; i<g.vexnum; i++)if(g.arcs[v][i])return i;return -1;/***********************************/
}//NextAdjVex
void CreateUDG(Graph &g)
{//采用邻接矩阵表示法,创建无向图G/****在此下面完成代码***************/cin>>g.vexnum>>g.arcnum;for(int  i=0; i<g.vexnum; i++)cin>>g.vexs[i];while(g.arcnum--){string x1,x2;cin>>x1>>x2;int m=LocateVex(g,x1),n=LocateVex(g,x2);if(m!=-1&&n!=-1)g.arcs[m][n]=g.arcs[n][m]=1;}/***********************************/
}//CreateUDN
void DestroyUDG(Graph &g)
{memset(g.arcs,0,sizeof(g.arcs));
}
//输出邻接矩阵
void PrintUDG(const Graph& g)
{int i, j;cout << "    ";for(i = 0; i < g.vexnum; i++){cout << setw(4) << g.vexs[i] ;}cout << endl;for(i = 0; i < g.vexnum; i++){cout << setw(4) << g.vexs[i];for(j = 0; j < g.vexnum; j++){cout << setw(4) << g.arcs[i][j];}cout << endl;}
}

AC代码

#include<bits/stdc++.h>
using namespace std;#define MVNum 100     //最大顶点数
typedef string VerTexType; //假设顶点的数据类型为字符串
typedef int ArcType;             //假设边的权值类型为整型//------------图的邻接矩阵------------------
typedef struct
{VerTexType vexs[MVNum];            //顶点表,用以存储顶点ArcType arcs[MVNum][MVNum];      //邻接矩阵int vexnum, arcnum;                //图的当前点数和边数
} Graph;
int LocateVex(const Graph &g, VerTexType v)
{//确定点v在G中顶点表的位置for(int i = 0; i < g.vexnum; ++i)if(g.vexs[i] == v)return i;return -1;
}//LocateVexint FirstAdjVex(const Graph &g, int v)
{//返回顶点v的第一个邻接点编号,没有返回-1/****在此下面完成代码***************/for(int i=0; i<g.vexnum; i++)if(g.arcs[v][i])return i;return -1;/***********************************/
}//FirstAdjVexint NextAdjVex(const Graph &g, int v, int w)
{//返回顶点v相对于w的下一个邻接点,没有返回-1/****在此下面完成代码***************/for(int i=w+1; i<g.vexnum; i++)if(g.arcs[v][i])return i;return -1;/***********************************/
}//NextAdjVexvoid CreateUDG(Graph &g)
{//采用邻接矩阵表示法,创建无向图G/****在此下面完成代码***************/cin>>g.vexnum>>g.arcnum;for(int  i=0; i<g.vexnum; i++)cin>>g.vexs[i];while(g.arcnum--){string x1,x2;cin>>x1>>x2;int m=LocateVex(g,x1),n=LocateVex(g,x2);if(m!=-1&&n!=-1)g.arcs[m][n]=g.arcs[n][m]=1;}/***********************************/
}//CreateUDNvoid DestroyUDG(Graph &g)
{memset(g.arcs,0,sizeof(g.arcs));
}//输出邻接矩阵
void PrintUDG(const Graph& g)
{int i, j;cout << "    ";for(i = 0; i < g.vexnum; i++){cout << setw(4) << g.vexs[i] ;}cout << endl;for(i = 0; i < g.vexnum; i++){cout << setw(4) << g.vexs[i];for(j = 0; j < g.vexnum; j++){cout << setw(4) << g.arcs[i][j];}cout << endl;}
}int main()
{Graph g;CreateUDG(g);//输出各个顶点的邻接点for(int i = 0; i < g.vexnum; i++){cout << g.vexs[i] << ":";for(int w = FirstAdjVex(g, i); w >= 0; w = NextAdjVex(g, i, w)){cout << ' ' << g.vexs[w];}cout << endl;}PrintUDG(g);DestroyUDG(g);return 0;
}

相关文章:

hnust 1963: 邻接矩阵表示法

hnust 1963: 邻接矩阵表示法 题目描述 输入一个图&#xff0c;用邻接矩阵存储&#xff0c;并实现一些操作。 拷贝下面的代码&#xff0c;按要求完成其中的FirstAdjVex&#xff0c;NextAdjVex和CreateUDG操作&#xff0c;其他地方不得改动。 //邻接矩阵表示图 #include <io…...

Hadoop-15-Hive 元数据管理与存储 Metadata 内嵌模式 本地模式 远程模式 集群规划配置 启动服务 3节点云服务器实测

章节内容 上一节我们完成了&#xff1a; Hive中数据导出&#xff1a;HDFSHQL操作上传内容至Hive、增删改查等操作 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机上搭建过一次&am…...

215.Mit6.S081-实验三-page tables

在本实验室中&#xff0c;您将探索页表并对其进行修改&#xff0c;以简化将数据从用户空间复制到内核空间的函数。 一、实验准备 开始编码之前&#xff0c;请阅读xv6手册的第3章和相关文件&#xff1a; kernel/memlayout.h&#xff0c;它捕获了内存的布局。kernel/vm.c&…...

flask使用定时任务flask_apscheduler(APScheduler)

Flask-APScheduler描述: Flask-APScheduler 是一个 Flask 扩展&#xff0c;增加了对 APScheduler 的支持。 APScheduler 有三个内置的调度系统可供您使用&#xff1a; Cron 式调度&#xff08;可选开始/结束时间&#xff09; 基于间隔的执行&#xff08;以偶数间隔运行作业…...

ApiFox或postman怎么用params类型传输json或集合+json的String类型

你是否碰见过这样的接口? post请求然后传输的参数都要和查询时一样以param形式传参数,那String什么的都好说,传就直接进后台了,那json呢,集合呢,是不是直接给你返400呢. 1.传json如何处理 那我们看看怎么实现,如果你要传json数据,那需要将特殊字符转义,也叫url转码,否则传不…...

数据结构第16节 最大堆

最大堆是一种特殊的完全二叉树数据结构&#xff0c;其中每个父节点的键值都大于或等于其子节点的键值。在Java中&#xff0c;最大堆通常用于实现优先队列&#xff0c;堆排序算法&#xff0c;或者在需要快速访问最大元素的应用场景中。 让我们通过一个具体的案例来说明最大堆的…...

显卡、显卡驱动、cuda、cuDNN之间关系

显卡、显卡驱动、CUDA 和 cuDNN 是构成高性能计算和深度学习环境的关键组件&#xff0c;它们之间有着紧密的联系。下面是对这些组件及其关系的详细介绍&#xff1a; 显卡&#xff08;GPU&#xff09; 显卡&#xff0c;全称为图形处理器&#xff08;Graphics Processing Unit&…...

Rewrk一个更现代的http框架基准测试实用程序

Rewrk一个更现代的http框架基准测试实用程序。HTTP基准测试&#xff08;HTTP benchmarking&#xff09;是一种测量和评估HTTP服务器或应用程序性能指标的活动。其目的是在特定条件下模拟大量用户请求&#xff0c;以测量服务器或应用程序的响应能力、吞吐量、延迟等指标&#xf…...

【算法】排序算法介绍 附带C#和Python实现代码

1. 冒泡排序(Bubble Sort) 2. 选择排序(Selection Sort) 3. 插入排序(Insertion Sort) 4. 归并排序(Merge Sort) 5. 快速排序(Quick Sort) 排序算法是计算机科学中的一个基础而重要的部分,用于将一组数据按照一定的顺序排列。下面介绍几种常见的排序算法,…...

360安全浏览器就是不行-python秒破解

下面画框都很容易破解&#xff0c;大家试试...

Python实现傅里叶级数可视化工具

Python实现傅里叶级数可视化工具 flyfish 有matlab实现&#xff0c;我没matlab&#xff0c;我有Python&#xff0c;所以我用Python实现。 整个工具的实现代码放在最后,界面使用PyQt5开发 起源 傅里叶级数&#xff08;Fourier Series&#xff09;由法国数学家和物理学家让-巴…...

PDF 分割拆分 API 数据接口

PDF 分割拆分 API 数据接口 文件处理&#xff0c;PDF 高效的 PDF 分割工具&#xff0c;高效处理&#xff0c;可永久存储。 1. 产品功能 高效处理大文件&#xff1b;支持多语言字符识别&#xff1b;支持 formdata 格式 PDF 文件流传参&#xff1b;支持设置每个 PDF 文件的页数…...

【python】随机森林预测汽车销售

目录 引言 1. 数据收集与预处理 2. 划分数据集 3. 构建随机森林模型 4. 模型训练 5. 模型评估 6. 模型调优 数据集 代码及结果 独热编码 随机森林模型训练 特征重要性图 混淆矩阵 ROC曲线 引言 随机森林&#xff08;Random Forest&#xff09;是一种集成学习方法…...

Stable Diffusion教程|练丹师是如何炼丹的Lora模型训练

前言 还记得我们之前就讲过学习SD成为炼丹师不&#xff1f;那么今天就来手把手教大家炼丹&#xff0c;看看同一个角色或某种风格的小模型是如何制作出来的。 目录 1 炼丹介绍 2 环境准备 3 Lora模型训练 **一、**炼丹介绍 什么是炼丹&#xff1f; 早在学习SD地第一篇就…...

QT--SQLite

配置类相关的表&#xff0c;所以我使用sqlite,且QT自带该组件&#xff1b; 1.安装 sqlite-tools-win-x64-3460000、SQLiteExpert5.4.31.575 使用SQLiteExpert建好数据库.db文件&#xff0c;和对应的表后把db文件放在指定目录 ./db/program.db&#xff1b; 2.选择sql组件 3.新…...

【深度学习入门篇 ②】Pytorch完成线性回归!

&#x1f34a;嗨&#xff0c;大家好&#xff0c;我是小森( &#xfe61;ˆoˆ&#xfe61; )&#xff01; 易编橙终身成长社群创始团队嘉宾&#xff0c;橙似锦计划领衔成员、阿里云专家博主、腾讯云内容共创官、CSDN人工智能领域优质创作者 。 易编橙&#xff1a;一个帮助编程小…...

Syslog 管理工具

Syslog常被称为系统日志或系统记录&#xff0c;是一种用来在互联网协议&#xff08;TCP/IP&#xff09;的网上中传递记录档消息的标准&#xff0c;常用来指涉实际的Syslog 协议&#xff0c;或者那些提交syslog消息的应用程序或数据库。 系统日志协议&#xff08;Syslog&#x…...

硅纪元AI应用推荐 | 百度橙篇成新宠,能写万字长文

“硅纪元AI应用推荐”栏目&#xff0c;为您精选最新、最实用的人工智能应用&#xff0c;无论您是AI发烧友还是新手&#xff0c;都能在这里找到提升生活和工作的利器。与我们一起探索AI的无限可能&#xff0c;开启智慧新时代&#xff01; 百度橙篇&#xff0c;作为百度公司在202…...

Codeforces Round 954 (Div. 3)

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;彩笔ACMer一枚。 &#x1f3c0;所属专栏&#xff1a;Codeforces 本文用于记录回顾本彩笔的解题思路便于加深理解。 &#x1f4e2;&#x1f4e2;&#x1f4e2;传送阵 A. X Axis解…...

【Django】报错‘staticfiles‘ is not a registered tag library

错误截图 错误原因总结 在django3.x版本中staticfiles被static替换了&#xff0c;所以这地方换位static即可完美运行 错误解决...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...