邻接表基本概念
图的邻接表存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。如词条概念图所示,表结点存放的是邻接顶点在数组中的索引。对于无向图来说,使用邻接表进行存储也会出现数据冗余,表头结点A所指链表中存在一个指向C的表结点的同时,表头结点C所指链表也会存在一个指向A的表结点。 [1]
邻接表是图的一种最主要存储结构,用来描述图上的每一个点。对图的每个顶点建立一个容器(n个顶点建立n个容器),第i个容器中的结点包含顶点Vi的所有邻接顶点。实际上我们常用的邻接矩阵就是一种未离散化每个点的边集的邻接表。
在有向图中,描述每个点向别的节点连的边(点a->点b这种情况)。
在无向图中,描述每个点所有的边(点a-点b这种情况)
与邻接表相对应的存图方式叫做边集表,这种方法用一个容器存储所有的边。
工业上有很多非常好的图库的实现,例如C++的boost graph库.如果可以,尽量用这些库,这样可以大大提高你的效率。
————以上摘自百度百科
实例![在这里插入图片描述](https://img-blog.csdnimg.cn/11f94009e08a4e0381aca12fb1462390.png#pic_center)
还是以这张图为例,他的邻接表长这样:
为什么邻接表长这样呢?来看看这张图画链式前向星的流程图吧:
接下来,让我们按着画链式前向星的主要思路来写写代码,来看道题:传送门
对立游戏邻接表
内存限制:4 MB
时间限制:0.100 S题目描述
自从有了邻接矩阵后,鸡哥可谓是战无不胜,爆击群雄,但这样也让鸡哥逐渐有了名气,慕名前来找他玩的人越来越多,邻接矩阵也不能投影在天花板上了,于是鸡哥戴上了隐形耳机,但是听总没有看好,这让鸡哥很是烦恼
现在来找鸡哥玩的人差不多有20多个,对立的行为差不多有100来个,一秒报20个并理解鸡哥可做不到,于是这个艰巨的任务就交给了小陈老师,但是小陈老师不会看邻接矩阵,并且这么多找起来也很困难。直到有一天鸡哥认识了邻接表,他才明白之前的邻接矩阵是多么废。
邻接表小陈老师能理解,于是你要重新设计一个程序来输出邻接表。但是小陈老师的电脑因为算力不够且误操作了某些设置,所以说他的电脑现在只有4MiB的内存可用。输入
第1行:
输入两个数N和M,代表n个人和m个对立行为
第2~M+1行:
每行输入两个整数i和j
表示i同学正在对立j同学输出
输出邻接表,第i行输出代表第i个人的被对立对象是j1,j2,jn…
若没有被对立对象则输出0样例输入
5 8
1 2
1 5
2 3
2 4
3 1
3 2
4 2
5 3样例输出
3
1 3 4
2 5
2
1提示
提示:每个同学的编号依次为1~N
对于57%的数据:N,M<=10
对于29%的数据:N,M<=100
对于14%的数据:N<=500,M<=103
由于作者太菜了,弄出的数据节点不大,所以说你要在100毫秒内输出结果
首先,我们先定义一些东西:(解释打注释里了)
#include<bits/stdc++.h>
using namespace std;
const int maxn=10001;//最大点数
int n,m;//n为点数,m为边缘数
vector<int> mp[maxn];//终点数组
然后第定义主函数:
int main(){
int u,v; cin>>n>>m;//输入人数与对立行为的数量
for(int i=1;i<=m;i++){
int u,v; cin>>u>>v;//输入终点起点
mp[v].push_back(u);//将v作为u的终点推入数组
}
for(int v=1;v<=n;v++){
for(auto it=mp[v].begin();it!=mp[v].end();it++){//这个begin会返回一个迭代器,你就当他是一个指针就好了
cout<<*it<<" ";//输出值加空格
}
if(mp[v].size()==0) cout<<0;//如果没有对立行为就输出0
cout<<endl;
}
}