Tarjan模板
Tarjan模板
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<cmath>
#include<limits.h>
#include<climits>
#include<fstream>
#include<set>
typedef long long ll;
using namespace std;
const int N = 1e5 + 5;
int cnt;//强连通分量的个数
int low[N], num[N], dfn;
int sccno[N], top;//sccno::SCC Number,就是第几个SCC的编号
int stack[N];
vector<int>G[N];
void dfs(int u)//u:父节点,v:子节点
{
stack[top++] = u;
low[u] = num[u] = ++dfn;//num[u]同时担负了判断是否进入的职责
for (int i = 0; i < G[u].size(); ++i)
{
int v = G[u][i];
if (!num[v])
{
dfs(v);
low[u] = min(low[v], low[u]);
}
else if (!sccno[v])//如果没有scc编号,但是又跳到跳过的位置
low[u] = min(low[u], num[v]);
}
if (low[u] == num[u])
{
cnt++;
while (1)//该点以上都是一个scc
{
int v = stack[--top];
sccno[v] = cnt;
if (u == v)break;
}
}
}
void Tarjan(int n)
{
cnt = top = dfn = 0;
memset(sccno, 0, sizeof(sccno));
memset(num, 0, sizeof(num));
memset(low, 0, sizeof(low));
for (int i = 1; i <= n; i++)
if (!num[i])
dfs(i);//防止不连通
}
int main()
{
int n, m, u, v;
cin >> n >> m;//n:点,m:边
for (int i = 0; i < m; i++)
{
cin >> u >> v;
G[u].push_back(v);
}
Tarjan(n);
return 0;
}
合集:
板子
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通