#include <stdio.h> #include <string.h> const int MAXN = 10000; /*********************************/ * 图G的邻接表表示 /*********************************/ int first1[MAXN]; int next1[MAXN]; int u1[MAXN],v1[MAXN]; /*********************************/ * 图Gt(G的转置)的邻接表表示 /*********************************/ int first2[MAXN]; int next2[MAXN]; int u2[MAXN],v2[MAXN]; int n,m; //n个顶点,m条边 int top[MAXN]; //拓扑序列 int pos; //拓扑序列下标 bool vis[MAXN]; //访问标记 int c[MAXN]; //连通分量内顶点记录 int cnt; /*********************************/ * DFS() /*********************************/ void dfs1(int i) { vis[i]=true; for(int j=first1[i];j!=-1;j=next1[j]) { if(!vis[v1[j]]) { dfs1(v1[j]); } } top[pos--] = i; } void dfs2(int i) { vis[i]=true; for(int j=first2[i];j!=-1;j=next2[j]) { if(!vis[v2[j]]) { dfs2(v2[j]); } } c[cnt++]=i; } /*********************************/ * DFS获取类似拓扑序列 * (因为图中可能有回路,不能严格算作拓扑序列) /*********************************/ void topList() { memset(vis,0,sizeof(MAXN)); pos=n-1; for(int i=0;i<n;++i) { if(!vis[i]) { dfs1(i); } } for(int j=0;j<n;++j) { printf("%d,",top[j]); } printf("/n"); } /*********************************/ * 有向图的强连通分量算法 * G与G的转置具有相同的分量 * 首先获得G的拓扑排序 * 然后按照拓扑序列,对G的转置 * 进行深搜,即可获得数个连通分量 * 简单原理:拓扑序列为顶点的访问次序 * 当两个不同的连通分量仅有一条边相连时 * 通过对G的转置,使得对G的转置的搜索 * 不会延伸到另一个分量内 * 所以,按照拓扑序列对Gt进行深搜 * 可以获取不同的连通分量 * 具体证明看算法导论 /*********************************/ void stronglyConnectedComponents() { topList(); memset(vis,0,sizeof(vis)); for(int i=0;i<n;++i) { cnt=0; if(!vis[top[i]]) { dfs2(top[i]); printf("连通分量:/n"); for(int j=0;j<cnt;++j) { printf("%d,",c[j]); } printf("/n"); } } } int main() { scanf("%d%d",&n,&m); memset(first1,-1,sizeof(first1)); memset(first2,-1,sizeof(first2)); for(int i=0;i<m;++i) { int a,b; scanf("%d%d",&a,&b); //构建G的邻接表 u1[i]=a; v1[i]=b; next1[i]=first1[a]; first1[a]=i; //构建Gt的邻接表 u2[i]=b; v2[i]=a; next2[i]=first2[b]; first2[b]=i; } stronglyConnectedComponents(); return 0; } /* 8 14 0 1 4 0 1 4 1 5 1 2 5 6 6 5 2 3 3 2 3 7 6 7 7 7 4 5 2 6 */
简单的理解写在代码里,
算法的过程: 输入图G,构造G的转置图Gt, DFS求G的一个拓扑序列(不是严格意义的DAG图), 按照拓扑序列次序对Gt实施DFS, 获取到每一个连通分量.