tarjan模板完整版
Posted shineeternal
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tarjan模板完整版相关的知识,希望对你有一定的参考价值。
https://www.luogu.org/problem/P2863
#include<cstdio>
#include<vector>
using namespace std;
int dfn[10005],low[10005],stack[10005],scc[10005],num[10005],vis[10005];
int clock,scc_cnt,top;
vector<int>e[10005];
inline void dfs_scc(int x)
dfn[x]=low[x]=++clock;//访问次序标记;x能到的祖先中节点编号最小的
stack[++top]=x;//把走过的节点入栈
vis[x]=1;
for(int i=0;i<e[x].size();i++)
int now=e[x][i];
if(!dfn[now])//如果没有被访问过
dfs_scc(now);//进它
low[x]=min(low[x],low[now]);//既然now是x的子节点,那么他们一定有公告的祖先,取个小的
else
if(vis[now])//如果他还没有被其他强连通分量使用
low[x]=min(low[x],dfn[now]);//那么再小一点
if(low[x]==dfn[x])
scc_cnt++;
while(stack[top]!=x)
//x节点在栈中夹着的节点就是强连通分量的节点
scc[stack[top--]]=scc_cnt;
vis[stack[top+1]]=0;
num[scc_cnt]++;
//哪一个点在当前编号为scc_cnt的强连通分量里
top--;
vis[x]=0;
num[scc_cnt]++;
scc[x]=scc_cnt;//一个强连通分量
int main()
int n,m,a,b;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d",&a,&b);
e[a].push_back(b);
//e[b].push_back(a);
int ans=0;
for(int i=1;i<=n;i++)
if(dfn[i]==0)
dfs_scc(i);
for(int i=1;i<=scc_cnt;i++)
if(num[i]>1)
ans++;
printf("%d\n",ans);
return 0;
以上是关于tarjan模板完整版的主要内容,如果未能解决你的问题,请参考以下文章