#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<stack>
using namespace std;
const int maxn = 1e5 + 10;
struct node
{
int next, to;
};
int tot, cnt, deep;
node edge[maxn<<1];
int dfn[maxn], color[maxn], low[maxn], vis[maxn], num[maxn];
int head[maxn];
stack<int>Q;
void add(int u, int to)
{
edge[tot] = (node){head[u], to};
head[u] = tot++;
}
void tarjan(int u)
{
vis[u] = 1;
dfn[u] = ++deep;
low[u] = deep;
Q.push(u);
for(int i = head[u]; ~i; i = edge[i].next)
{
int v = edge[i].to;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else
{
if(vis[v])
{
low[u] = min(low[u], low[v]); // dfn[v];
}
}
}
if(dfn[u] == low[u])
{
color[u] = ++cnt;
vis[u] = 0; // 别漏了,会造成u在栈里面的假象
while(Q.top() != u)
{
color[Q.top()] = cnt;
vis[Q.top()] = 0;
Q.pop();
}
Q.pop();
}
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
cnt = 0;
deep = 0;
memset(head, -1, sizeof(head));
tot = 0;
for(int i = 0; i < m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
}
for(int i = 1; i <= n; i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
for(int i = 1; i <= n; i++)
{
num[color[i]]++;
}
int ans = 0;
for(int i = 1; i <= cnt; i++)
{
// printf("%d\n", num[i]);
if(num[i] > 1)
ans++;
}
printf("%d\n", ans);
return 0;
}
tarjan求强连通分量入门
猜你喜欢
转载自blog.csdn.net/weixin_43891021/article/details/102759907
今日推荐
周排行