题意:给n给点,m条边,求连通分量>=2的强联通分量数;
思路:直接上模板即可
scc_cnt为SCC的计数器,sccno[i]为i所在的SCC编号。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
using namespace std;
const int maxn = 10010;
vector<int>g[maxn];
int pre[maxn],low[maxn],sccno[maxn],dfs_clock,scc_cnt;
int a[maxn*5],b[maxn*5];
int num[maxn];
stack<int>s;
int ans;
void dfs(int u)
{
pre[u] = low[u] = ++dfs_clock;
s.push(u);
for(int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
if(!pre[v])
{
dfs(v);
low[u] = min(low[u],low[v]);
}
else if(!sccno[v])
{
low[u] = min(low[u],pre[v]);
}
}
if(low[u]==pre[u])
{
scc_cnt++;
for(;;)
{
int x = s.top();
s.pop();
sccno[x] = scc_cnt;
if(x==u)
break;
}
}
}
void find_scc(int n)
{
dfs_clock = scc_cnt = 0;
memset(sccno,0,sizeof(sccno));
memset(pre,0,sizeof(pre));
for(int i = 0; i < n; i++)
if(!pre[i])
dfs(i);
}
int main()
{
int n,m;
ans = 0;
cin >> n >> m;
for(int i = 0; i < m; i++)
{
cin >> a[i] >> b[i];
g[a[i]-1].push_back(b[i]-1);
}
find_scc(n);
memset(num,0,sizeof(num));
for(int i = 0; i < n; i++)
num[sccno[i]]++;
for(int i = 1; i <= scc_cnt; i++)
{
if(num[i]>=2)
ans++;
}
cout << ans << endl;
return 0;
}
本文介绍了一种计算图中强连通分量的方法,并通过一个具体的C++实现示例来展示如何找出所有连通分量数大于等于2的强连通分量。

被折叠的 条评论
为什么被折叠?



