求有向图中强连通分量的个数
#include<cstdio> #include<vector> #include<cstring> using namespace std; const int MAX_N=10005; vector<int> G[MAX_N]; vector<int> rG[MAX_N];//存储边反向之后的图 vector<int> PostOrder;//存储图的后序遍历 int V,E; bool used[MAX_N]; int comp[MAX_N];//存储每个结点所属的联通分量 void addEdge(int u,int v) { G[u].push_back(v); rG[v].push_back(u); } void dfs(int u) { used[u]=true; for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(!used[v]) dfs(v); } PostOrder.push_back(u); } void rdfs(int u,int k) { used[u]=true; comp[u]=k; for(int i=0;i<rG[u].size();i++) { int v=rG[u][i]; if(!used[v]) rdfs(v,k); } } int scc() { memset(used,false,sizeof(used)); for(int i=1;i<=V;i++) { if(!used[i]) dfs(i); } memset(used,false,sizeof(used)); int k=0; for(int i=PostOrder.size()-1;i>=0;i--) { int v=PostOrder[i]; if(!used[v]) rdfs(v,k++); } return k; } int main() { scanf("%d %d",&V,&E); for(int i=0;i<E;i++) { int u,v; scanf("%d %d",&u,&v); addEdge(u,v); } printf("%d\n",scc()); return 0; }