最近,同期的一位大佬给我出了一道题目,改编自 洛谷 P2783 有机化学之神偶尔会做作弊
这道题好坑啊,普通链表过不了,只能用vector来存边。可能更快一些吧?
所以,我想记录并分享一下vector怎么实现邻接表。
I:存边
通常我们用的链表结构需要自己打一个add函数
int cnt,head[maxn]; struct edge { int next,to,cost; } e[maxn]; void add(int a,int b,int c) { e[++cnt].to=b;e[cnt].cost=c; e[cnt].next=head[a];head[a]=cnt; }
但是,vector来存储就不需要这么复杂。我们还是要一个结构体,但是不需要用e.next和head[]数组。
然后,我们要明确vector数组的下标是什么。请看代码中详解。
struct edge { int to,cost; }; vector <edge> e[maxn];//表示以i为起点的所有边 //p.s. 此时定义的看似是一维数组,实际上是有两个维度 //例如 e[x][i].to 表示的是以x为起点,第i条边的to。 //而 存边就是这样 在main函数里直接: int t;edge f; scanf("%d%d%d",&t,&f.to,&f.cost); e[t].push_back(f);
II:遍历
遍历十分简单,直接一遍循环,找e[x]这个数组里面的所有边。
这里我们要用到一个函数 e[x].size() 表示数组大小。
//假设遍历到了x点 for (int i=0;i<s[x].size();i++) { int from=s[x][i].to;//这是与x点相连的i边的to int w=s[x][i].cost;//同理 这是cost }
就这样 vector就可以实现邻接表了。
是不是比链式前向星更加简洁呢?