邻接表:
太多用链表来写邻接表的了,主包的评价是链表太复杂,直接用c++中 vector 向量实现存图
直接上一个小题
该题也是非常好理解就是树和dfs,但由于树就是特殊的图所以我们直接用存图方式来存树
先来个代码再解释
#include<bits/stdc++.h>
using namespace std;
bool vis[100010];
vector<int>a[100010];
int n, d,ans;
void dfs(int now, int dis) {
vis[now] = 1;
if (dis == d)return;
for (int i = 0; i <a[now].size(); i++) {
if (!vis[a[now][i]]) {
dfs(a[now][i], dis + 1);
ans++;
}
}
}
int main() {
memset(vis, 0, sizeof(vis));
cin >> n >> d;
for (int i = 1; i <= n-1; i++) {
int x, y;
cin >> x >> y;
a[x].push_back(y);
a[y].push_back(x);
}
dfs(1, 0);
cout << ans;
return 0;
}
vis为标记数组标记是否访问过该结点,因为是无向图,所以我们的存储是
int x, y;
cin >> x >> y;
a[x].push_back(y);
a[y].push_back(x);
该插入数据相当于一个尾插法
所以将测试数据放进去就是
(a[i][j] i为第i个节点,j为此节点的下一个节点)用size来代替长度,每个存储的数据就是
a[1][size]=1
a[2][size]=1,4
a[3][size]=5
从第一个节点开始遍历,如果没有被遍历过就打上标记再进行遍历该结点下一个节点,直到树的深度为d,返回寻找别的未遍历的结点,并且能访问的结点数加一。
如果有需要权值的话就创建一个结构体数组再vector来存图
(主包的评价也是非常好用)
链式前向星
模拟链表采用头插法
以边为基本单位,记录每一条边的目标点
链式前向星包含
head数组 edge数组
直接上上个题解法代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct edge{
int v, nxt;
}e[200010];
int head[200010], cnt, n, d, x, y, vis[100010];
inline void add(int u, int v){
e[++cnt].v = v;
e[cnt].nxt = head[u];
head[u] = cnt;
}//链式前向星建图
void dfs(int u){//求深度
for(int i = head[u]; i; i = e[i].nxt){
int v = e[i].v;
if(vis[v]) continue;//已经遍历过就不遍历了
vis[v] = vis[u] + 1;//深度+1
dfs(v);//继续搜索
}
return;
}
int main(){
scanf("%d%d", &n, &d);
for(int i = 1; i < n; ++i){
scanf("%d%d", &x, &y);
add(x, y);
add(y, x);//注意是无向图
}
int ans = 0;
dfs(vis[1] = 1);//压行QWQ
for(int i = 2; i <= n; ++i) if(vis[i] - 1 <= d) ans++;//vis[i] - 1即为1到i的距离
printf("%d", ans);
return 0;
}
链式前向星最关键的部分
inline void add(int u, int v) {
e[++cnt].v = v;//cnt为edge索引
e[cnt].nxt = head[u];
//类似头插法,先取得头结点的信息,再更新头节点
head[u] = cnt;//更新头结点
}//链式前向星建图
因为该树没有权值,所以结构体中不需要加权值,但如果是存图的话很多都有权值
先将head全部初始化为0,当该结点第一次被使用时则next指向0,然后不断更新头结点
主包觉得这还是太难解释了建议直接打开b站
【【图论02】动画说图的三种保存方式 降低理解门槛 邻接表 链式前向星 邻接矩阵】https://www.bilibili.com/video/BV1n94y1u7s2?vd_source=b48332c6ec56a2e8b2e1393a7e468c59
最后再总结一下:
邻接表以点为基本单位进行尾插
链式前向星以边为基本单位进行头插
空间复杂度差异不大,区别在于对不同图进行操作
在遍历不同结点还是寻找特点边可能有不同效率