题意:给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; }