图的存储和遍历
1.C++内存四区2.算法-排序-快速排序3.算法-排序-归并排序4.c++重载5.算法-二分6.算法—前缀和7.算法—差分8.算法-双指针9.c++引用10.c++函数默认参数及占位参数11.c++函数模板12.c++类和对象-封装13.struct和class的区别14.成员属性设置为私有15.C++类和对象-对象特性(1)16.C++类和对象-对象特性(2)17.N皇后18.动态规划dp-01背包问题19.C++类和对象-对象特性(4)20.C++类和对象-对象特性(3)21.C++友元22.C++运算符重载23.C++继承24.C++多态25.C++类模板26.C++vector容器27.C++string容器28.C++deque容器29.算法-树状数组30.算法线段树31.算法-bfs32.算法-贪心33.算法-Flood Fill34.数据结构-链表35.数据结构-栈36.数据结构-队列37.P2678 跳石头38.5132139.54440.3213241.牛客寒假算法集训1-总结42.牛客寒假算法集训2-总结43.牛客寒假算法集训3-总结44.数论-质数45.博弈论46.第十四届蓝桥杯省赛C++题解47.Trie树48.并查集49.数据结构-堆50.哈希表51.拓扑排序52.Dijkstra53.spfa54.数论-约数55.数论-欧拉函数
56.图的存储和遍历
57.牛客寒假算法集训4-总结58.牛客寒假算法集训5-总结59.牛客寒假算法集训6-总结60.Bellman_ford61.Floyd62.编辑距离63.数位dp一.存储
树是特殊的图
无向图是特殊的有向图 所以只需考虑有向图如何存储即可
1.邻接矩阵 空间复杂度o(n^2)-用的不多
2.邻接表(每一个节点都开一个单链表-存这个点可以走到哪个点)
注:内部点顺序无关紧要
二.遍历
(1)深度优先遍历DFS
#include <iostream>
#include <algorithm>
#include <cstring>
#define endl '\n'
using namespace std;
const int N=1e5+10;
int h[N];//头节点
int e[N*2],ne[N*2],idx;//与单链表一样
bool st[N];//判重数组
int ans=N;//最大值
int n;
void add(int x,int y)//与单链表插入一样
{
e[idx]=y;
ne[idx]=h[x];
h[x]=idx++;
}
int dfs(int u)//深度遍历图
{
st[u]=true;//已经遍历过了
int res=0;//代表删除u节点的树点个数的最大值
int sum=1;//指根子树的点数
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(!st[j])
{
int s=dfs(j);//当前子树的大小
res=max(res,s);//取最大值
sum+=s;//是以u节点的树的一部分
}
}
res=max(res,n-sum);//节点上面也要算
ans=min(res,ans);
return sum;
}
int main()
{
cin>>n;
memset(h,-1,sizeof h);//初始化-1表示空节点
for(int i=0;i<n-1;i++)
{
int a,b;
cin>>a>>b;
add(a,b);add(b,a);
}
dfs(1);
cout<<ans<<endl;
return 0;
}
(2)宽度优先遍历BFS
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N=1e5+10;
queue<int> q;//队列
int h[N],e[N*2],ne[N*2];
int idx;//当前用到的下标
int n,m;
int d[N];//标记数组
void add(int a,int b)//插入
{
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
int bfs()
{
q.push(1);//起始点入队
memset(d,-1,sizeof d);//初始化标记数组 -1表示没有遍历过
d[1]=0;//起始点遍历过了
while(!q.empty())//BFS
{
auto t=q.front();//取出队头元素
q.pop();//elimate
for(int i=h[t];i!=-1;i=ne[i])
{
int j=e[i];
if(d[j]==-1)
{
d[j]=d[t]+1;//更新标记数组
q.push(j);
}
}
}
return d[n];
}
int main()
{
cin>>n>>m;
memset(h,-1,sizeof h);
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
add(a,b);
}
cout<<bfs()<<endl;
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验