在图中找到一个最大的子图,使这个子图中每个两点都能够互相到达,这个最大的子图称为强连通分量,同时一个点也是属于强连通分量的。主要是通过dfs来实现的,在dfs的过程中维护了几个东西:一个stack用来存访问过的节点,就是靠栈来存的强连通分量的节点的,要一个dfn数组用于记录节点的时间戳,每个节点的dfn值是不会变的,还有最后一个是low数组,我的理解是对于low[i]来说,low[i]记录的是包含了i节点的强连通分量(也可以理解为强连通分量树)的根节点的dfn值,也可以理解为i通过i子树里的点能访问到的dfs树里最早的节点。
1,2,3为一个scc,4为一个scc,5为一个scc
int n,sccn,cnt,dfn[105],low[105],scc[105];//sccn记录scc个数,scc【i】记录i属于的scc
vector<int>g[105];
stack<int>sta;
void dfs(int now){
dfn[now]=low[now]=++cnt;
sta.push(now);
for(int i=0;i<(int)g[now].size();i++){
int v=g[now][i];
if(!dfn[v]){
dfs(v);
low[now]=min(low[now],low[v]);
}else if(!scc[v]){
low[now]=min(low[now],dfn[v]);
}
}
if(low[now]==dfn[now]){//缩点操作,把图缩为sccn个点,要得到新图的话,枚举原来的边,然后如果两个点对应的scc不同则连边
sccn++;
for(;;){
int tmp=sta.top();sta.pop();
scc[tmp]=sccn;
if(tmp==now) break;
}
}
}
推荐一篇入门博客https://blog.csdn.net/qq_34374664/article/details/77488976