存图方法——vector
本文章是作者学习OI过程中存在的疑惑,希望可以直接解决你的疑惑。
是c++stl库中一种存图方法,是不定长数组,根据输入的数据多少而决定所开空间大小(通俗理解)
头文件(必须)#include<vector>
vector<所开数组的类型> 数组名(可以是数组);
(通俗理解,vector数组比直接声明的多一维)
下一步是读入;
数组名.push_back(读入的数据);
在很多图论基础题中,vector要开到两维;
这时 输入变为
数组名[ x ].push_back(读入的数据);
这里用代码体现
vector<int> t[10007];//声明vector for(int i=1;i<=m;i++)//存边; { int x,y; cin>>x>>y;//x,y,表示点x、y间连同着一条边; t[x].push_back(y); }
(至于有边权的情况我个人觉得用前向星好)
下面是访问,这里对于初次接触vector比较抽象,不知道什么代表什么的大有人在,比如我。
那就以上面这个代码为例子。
在读入后vector数组是这样的:
t[i][j]=w
好,此时他的意义是以点i为起点的第j条边通向w;(根据上文读入代码:i=x,w=y,j自增)
所以j的数值是随着输入而不断增加的,这就是为什么,vector被称为不定长数组。
本人理解,深度不够,但希望对和我一样初学OI的同志们先了解vector基本模式。
7.8更新。
我自己很少用vector,因为我不会用更多维的vector和vector数组。
但今天看了同机房OIer的代码,茅塞顿开。
我们可以定义
vector<int> G[10001][21];
他实际上等于发G[第一维][第二维][第三维]
其中第1、2维我们自己输入,第三维根据我们输入的次数自增。
输入:G[x][y].push_back(z)
访问时为G[x][y][i]=z(i表示第几条边,自增)
x,y,z,可以根据需要定义,实质上与二维vector并没有很大区别
另外这里我不建议通过开多一维的方式存边权,建议开结构体vector;
初始化:vector<结构体名> G[10001][21];
读入:q[x][y].push_back((结构体名字){读入的数据})
这里举个例子直观体现:
struct edge { int to, w;//表示终点,权值。 }; int n, m, k; vector<int> G[10001]; int main() { scanf("%d%d%d", &n, &m);//表示点数,边数。 for (int i = 1; i <= m; i++) { int a, b, c;//代表一个边起点,终点,权值。 scanf("%d%d%d", &a, &b, &c); G[a].push_back((edge) {b, c});//按照结构体类型强压,变量顺序要按照在结构体中定义的顺序。 } G[a][i].to; //以a为起点的第i条边终点为to(前面村的对应的c) G[a][i].w;//同理。 //对于像迪杰斯特拉等需要遍历以某点为起点的我们照样i<=G[a].size即可 return 0; }
7.16更新。
当用vector存图,我们需要访问时,枚举i。
for(int i=0;i<g[u].size();i++)//size为存了i的个数.
注意一定是“<(>)”不是“<=(>=)”不然会炸空间。
如有不足,请指出,感谢。