DFS序
DFS序
DFS序,算法如其名就是用DFS搞的序。没有学过DFS的同学先去看看吧(基本中的基本)这个算法就是依靠DFS将一个树状图用线性结构进行排列。因为树形结构每次更新查找总是很费时间,如果我们可以用某种方法把它转变成线性结构就可以用线段树或者树状数组很轻松地记录了。
要将一个树进行线性排列,我们就需要记录每个根所含的叶子。这个问题可以用时间戳来搞定。(其实这个戳就是个记录的数字,每次dfs一个点就++,当一个点dfs完所有子叶之后比较之前记录它自身的记录的数字就可以确定他的子叶个数和分别是什么了)
废话说太多。我们来看下这个图(转自网络侵删)
DFS一般从根节点1开始,每次深度优先遍历点,一般是【根,左叶到右叶】(这个叫什么序有同学知道告诉我我忘了)比如这个图的次序就是[2,4,7,1,3,6,5]
时间戳怎么实现呢?用两个数组in[] out[]和一个戳cnt,每dfs一个点i就cnt++并in[i]=cnt,遍历完子点再out[i]=cnt(cnt是全局变量)
实现
int time = 0;
inline void dfs(int x, int fa) {
in[x] = ++time;
num[time] = x;
for(int i = 0; i < G[x].size(); i++) {
int cnt = G[x][i];
if(cnt == fa) continue;
dfs(cnt, x);
}
out[x] = time;
}
当然,dfs序也可以变无向图为线性结构,就是把图变成一个生成树。
tarjan就是基于这个算法达到的。
#include<iostream> #include<cstdio> #include<vector> using namespace std; struct gh { int v,w; gh(){}; gh(int _v,int _w):v(_v),w(_w){} }; vector<gh> g[100]; int k,d[1000],n; int sech(int); int main() { freopen("dfs.in","r",stdin); int x,y,z; cin >> n; for(int i=1;i<=n;i++) { scanf("%d%d%d",&x,&y,&z); g[x].push_back(y); g[y].push_back(x); } sech(1); for(int i=1;i<=n+1;i++) cout<<d[i]; } int sech(int u) { int v; d[u]=++k; for(int j=0;j<g[u].size();j++) { v=g[u][j]; if(d[v]==0) sech(v); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现