给你n个点,m条边,求图中所有大小大于1的强连通分量的个数
输入样例#1:
5 4 2 4 3 5 1 2 4 1
输出样例#1:
1
显然是tarjan,求出强连通分量的个数,给每个强连通分量的点染色,统计出每个强连通分量中点的个数,如果大于一,则答案加一。
#include <bits/stdc++.h>
using namespace std;
using ll=long long ;
const int maxn=20005;
int n,m;
std::vector<int> G[maxn];
int dfn[maxn],low[maxn],vis[maxn],belong[maxn],cnt[maxn];
std::stack<int> s;
int deep,sum,ans;
void tarjan(int u)
{
dfn[u]=low[u]=++deep;
vis[u]=1;
s.push(u);
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u])
{
belong[u]=++sum;
vis[u]=0;
while(s.top()!=u)
{
belong[s.top()]=sum;
vis[s.top()]=0;
s.pop();
}
s.pop();
}
}
int main(int argc, char const *argv[])
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
int u,v;scanf("%d%d",&u,&v);
G[u].emplace_back(v);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i]) tarjan(i);
}
for(int i=1;i<=n;i++)
cnt[belong[i]]++;
for(int i=1;i<=sum;i++)
if(cnt[i]>1) ans++;
printf("%d\n", ans);
return 0;
}