浅谈Tarjan算法
Tarjan算法:
Tarjan算法是一种用于查找已知图中的强连通分量的方法(介绍似乎越来越草率了
时间复杂度:O(n+m)//n为点数,m为边数
算法思路:
1,首先对每个节点设置两个参数存储:dfn[i]表示第i个点被搜索到的次序编号(每个点的dfn值都不同,low[i]表示每个点在这棵树中的最小子树根(人话就是找爹;
2,对每个新节点,初始化零dfn[i]=low[i];
3,用栈作为容器存储新出现的节点,若这个点有出度,就依次遍历每个子节点,每次都更新最小值保证子树根最小;
4,若找到dfn[i]=low[i],则i为本强连通分量中的根节点,将i及比i后进栈的元素出栈,即为一个强连通分量;
5,应在循环中调用tarjan函数,使每个没被访问过的点都被访问到。
似乎没找到板子题那就自己创造板子吧。
似乎很简单不太用注释的样子。
#include<bits/stdc++.h> #define ri register int using namespace std; const int N=1e4; int n,m; int head[N],cnt; bool vis[N]; int dfn[N],low[N],tot; struct qwq{ int to,nxt; }e[N]; stack<int> s; void add(int u,int v){ e[++cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } void tarjan(int x){ dfn[x]=low[x]=++tot; s.push(x); vis[x]=1; for(ri i=head[x];i;i=e[i].nxt){ int v=e[i].to; if(!dfn[v]){ tarjan(v); low[x]=min(low[x],low[v]); } else if(vis[v]) low[x]=min(dfn[v],low[x]); } if(low[x]==dfn[x]){ for(;;){ int u=s.top(); s.pop(); printf("%d ",u); if(u==x) break; } putchar('\n'); } } int main(){ scanf("%d%d",&n,&m); int x,y; for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); add(x,y); } for(int i=1;i<=n;i++) if(!vis[i]) tarjan(i); return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析