图论算法(一)存图

我发现我的博客阅读量贼低,问小伙伴们,ta们都说这些博客太长了QAQ!

今天来个短亿点的(也短不了多少……)

进入正题,图论究竟是什么?

图论就是给你一张图,让你在这张图上进行各种操作,但是我们要进行操作之前,要先明白图是什么。

如果你还不了解图是什么,我这里稍微BB一两句,如果你已经了解了图是什么,请直接去第二部分!

Part 1:图是什么

我们先看一张图片:

假设有1,2,3,4,5五座城市,

我们用5个标号的圆圈(1,2,3,4,5)来表示这5个城市。

其中有一些城市之间有公路,有一些没有(用连线表示)。

每一条公路也有一定的长度(已经在连线上表出),公路是双向的(这很重要)。

综合这些元素,我们就得到了上面这个基本的“图”。

这就是图的基本元素。

我们用一些术语来表示刚才提到的这些元素。

城市叫做“点”,图的基本元素就是点和边。

公路叫做“边”,边分为有向边和无向边,有向边就是只能从A到B但是不能从B到A(你可以理解是A市和B市中有一条A->B的单行线),无向边可以任意来回走。

公路的长度叫做“权”,代表两个“点”之间的距离。当然,图是抽象的而不是现实世界中存在的,这个距离就可以使负的,我们叫它“负权”。

如果几个边把几个点连成了一个环形,我们叫它“环”。

如果一个点有一条边指向了自己,我们叫它“自环”。

如果一个环的所有构成边的权值和为负,我们就叫他“负环”(我叫他自闭环,因为出现自闭环的图中会导致无限循环,无法算出最短路等……)

Part 2:怎么存图

有两种数据结构可以用来存图,而且这两种数据结构都很好想也很简单实现,大概小学生都能想出来。

第一种,我们叫它“邻接矩阵”。

所谓邻接矩阵,就是指一个n*n(n是图中点的个数)的int数组。

比如我这么写:

#define N 110
int v[][];

这个数组就可以表示一个有109个点的图,具体我们用v[i][j]表示第i个点到第j个点的边的长度(点i->点i ==0,如果 点i->点j 没有边相连,记为0x3f)。

邻接矩阵有如下特性:

1、空间复杂度O(n^2),这里要注意空间会不会爆炸,比如题目中n<=10^5,我们就不能用邻接矩阵。

2、对于图的指定边的更新操作,复杂度为O(1)。

具体代码如下:(给出n个点m条边,给出第i条边是x->y权值为z)

#include<cstdio>
#include<cstring>
#define N 1010
#define IAKIOI 0
using namespace std;
int n,m,v[N][N];
int main()
{
memset(v,0x3f,sizeof(v));
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
v[x][y]=z;
}
for(int i=;i<=n;i++)
v[i][i]=;
return IAKIOI;
}

下面介绍第二种存图的方法——邻接表

首先我们要知道C++STL库里有一个容器叫做vector,它可以动态地申请空间,这样就节省了邻接矩阵存下“不存在的边”而浪费的宝贵空间。

下面是邻接表的实现方法

1 2(1) 3(2)
2 1(1) ——
3 2(3) ——

像这个表格,(标记——的是未使用的内存空间)我们用第一列的数字代表点i,后面跟着的一行表示从点i出发可以到达的点(点没有括号)和边权(边权用括号括起来了)。

比如第一行的意思就是:点1可以到点2,距离为1,点1可以到点3,距离为2。

这样我们节省了两个内存空间,当点的数量非常大的时候,节省的空间是非常可观的。

但是邻接表也有弊端,vector容器调用起来比较慢,我们如果要对一个边进行修改,只能遍历邻接表的某个一维空间,不像邻接矩阵一样可以直接用下标访问。

Part 3:vector容器

好了在给出邻接表代码之前我们先康康vector容器是什么东西。

很简单来说,vector容器就是一个可以任意更改长短的向量,我们可以存下不超过它的长度的数据,当然也可以随时给他增加长度或者减少长度。

既然是STL模板库里的东西,必定有一些配套的函数,我知道的有以下几个:

#include<cstdio>
#include<vector>
using namespace std;
vector<int>vec;
int main()
{
int len=vec.size();//返回元素个数
vec.push_back();//把“1”插入到vector末尾(先增加一个空间)
vector<int>::iterator it;//定义一个指针it(迭代器)
it=vec.begin();//迭代器指向第一个元素
it=vec.end();//迭代器指向最后一个元素
for(unsigned int i=;i<vec.size();i++)//用unsigned,不然会警告错误(不用也没事)
{
//……访问每个元素
}
for(vector<int>::iterator it=vec.begin();it!=vec.end();it++)//和上面等价的指针写法
vec.clear();//清空vector,但不回收内存
vector<int>().swap(vec); //清除容器并回收内存
}

上面就是vector的基本用法(其实写邻接表用不了这么多,但是阔以了解一下……)

下面回到邻接表部分:

给出代码:

#include<cstdio>
#include<vector>
#define N 10010
using namespace std;
struct Node{
int to,cost;//to表示到达点,cost表示权值
};
int n,m;
vector<Node>v[N];//N个vector容器表示N个点的路径情况(看上面的表格就明白)
int main()
{
scanf("%d%d",&n,&m);//n个点m条边的图
for(int i=;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
v[x].push_back((Node){y,z});//x点到y点有权值为z的边
//v[y].push_back((Node){x,z});无向图要加这句话反向建边
}
return ;
}

以上就是邻接表和邻接矩阵存图的思路和代码,(还有vector的一点点知识,学会了这些就可以开启下一篇的知识——图论啦!)

图论算法(一)存图与STL第六弹——vector容器的更多相关文章

  1. 标准模板库(STL)学习探究之vector容器

    标准模板库(STL)学习探究之vector容器  C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...

  2. C++STL(二)——vector容器

    STL--vector容器 vector对象的概念 vector基本操作 vector对象的初始化.赋值 vector查找.替换(已在上一片 string类 博客总结过了,不再总结) vector添加 ...

  3. STL学习二:Vector容器

    1.Vector容器简介 vector是将元素置于一个动态数组中加以管理的容器. vector可以随机存取元素(支持索引值直接存取, 用[]操作符或at()方法,这个等下会详讲). vector尾部添 ...

  4. STL之二:vector容器用法详解

    转载于:http://blog.csdn.net/longshengguoji/article/details/8507394 vector类称作向量类,它实现了动态数组,用于元素数量变化的对象数组. ...

  5. 带你深入理解STL之Vector容器

    C++内置了数组的类型,在使用数组的时候,必须指定数组的长度,一旦配置了就不能改变了,通常我们的做法是:尽量配置一个大的空间,以免不够用,这样做的缺点是比较浪费空间,预估空间不当会引起很多不便. ST ...

  6. 浅谈C++ STL vector 容器

    浅谈C++ STL vector 容器 本篇随笔简单介绍一下\(C++STL\)中\(vector\)容器的使用方法和常见的使用技巧.\(vector\)容器是\(C++STL\)的一种比较基本的容器 ...

  7. 最短路 spfa 算法 && 链式前向星存图

    推荐博客  https://i.cnblogs.com/EditPosts.aspx?opt=1 http://blog.csdn.net/mcdonnell_douglas/article/deta ...

  8. C++算法 链式前向星存图

    这个东西恶心了我一阵子,那个什么是什么的上一个一直是背下来的,上次比赛忘了,回来有个题也要用,只能再学一遍,之前也是,不会为什么不学呢.我觉得是因为他们讲的不太容易理解,所以我自己给那些不会的人们讲一 ...

  9. 图论算法(四)Dijkstra算法

    最短路算法(三)Dijkstra算法 PS:因为这两天忙着写GTMD segment_tree,所以博客可能是seg+图论混搭着来,另外segment_tree的基本知识就懒得整理了-- Part 1 ...

随机推荐

  1. 最小生成树的java实现

    文章目录 一.概念 二.算法 2.1 Prim算法 2.2 Kruskal算法 笔记来源:中国大学MOOC王道考研 一.概念 连通图:图中任意两点都是连通的,那么图被称作连通图 生成树:连通图包含全部 ...

  2. 2020最新全栈必备 Redis,你还不了解么

    什么是Redis Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如字符串, 散列, 列表, 集合, 有序集合与范围查 ...

  3. Dom运用2

    1.登录系统 <!--输入框创建--> 账号:<input class="ipt" type="text"><br> 密码: ...

  4. 渲染导航菜单的同时给每个菜单绑定不同的router跳转

    这个问题一开始的时候,我总想着router跳转只有两种方式 一种@click,一种router-link 然后我想着@click,绑定一个事件,事件下面无法确定我当前是哪个菜单,解决不了. 然后< ...

  5. statsmodels 示例

    Statsmodels 示例 https://www.statsmodels.org/stable/examples/index.html

  6. Linux最常用的基本操作复习

    .ctrl + shift + = 放大终端字体 .ctrl + - 缩小终端字体 .ls 查看当前文件夹下的内容 .pwd 查看当前所在的文件夹 .cd 目录名 切换文件夹 .touch 如果文件不 ...

  7. PHP is_link() 函数

    定义和用法 The is_link() 函数检查指定的文件是否是一个连接. 如果文件是一个连接,该函数返回 TRUE. 语法 is_link(file) 参数 描述 file 必需.规定要检查的文件. ...

  8. C/C++编程笔记:C++入门知识丨多态性和虚函数

    本篇要学习的内容和知识结构概览 多态性 编译时的多态性称为静态联编. 当调用重载函数时, 在编译期就确定下来调用哪个函数. 运行时的多态性称为动态联编. 在运行时才能确定调用哪个函数, 由虚函数来支持 ...

  9. 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心

    LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...

  10. 6.29 省选模拟赛 坏题 AC自动机 dp 图论

    考场上随手构造了一组数据把自己卡掉了 然后一直都是掉线状态了. 最后发现这个东西不是subtask -1的情况不多 所以就没管无解直接莽 写题有点晚 故没调出来.. 考虑怎么做 容易想到建立AC自动机 ...