对于强连通还是不能很好的理解dfn和low数组解决强连通分量的问题。但是模板其实很好记。
int top;//栈顶指针
int stack[maxn];//栈
bool vis[maxn];//表示是否在栈中
int dfn[maxn], low[maxn];
//dfn记录到i点的时间,low表示该点直接或间接到达的点的时间
int bcnt , dindex;
//bcnt表示联通个数,dindex表示到达某个点的时间
vector<int> vec[maxn];//存边的邻接表
void tarjan(int u)
{
int v = 0;
dfn[u] = low[u] = ++dindex;
vis[u] = true;
stack[++top] = u;
int t = vec[u].size();
for(int i=0; i<t; i++)
{
v = vec[u][i];
if(dfn[v] == -1)
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(vis[v])
low[u] = min(low[u], dfn[v]);
}
if(dfn[u] == low[u])//找到一个强连通
{
bcnt++;
do{
v = stack[top--];
vis[v] = false;
}while(u != v);
}
}
int main()
{
bcnt = dindex = top = 0;
memset(dfn, -1, sizeof(dfn));
memset(vis,false,sizeof(vis));
for(int i=0; i<maxn; i++)
vec[i].clear();
for(int i=1; i<=N; i++)
if(dfn[i] == -1) tarjan(i);
}
Low数组是一个标记数组,记录该点所在的强连通子图所在搜索子树的根节点的Dfn值
Dfn数组记录搜索到该点的时间,也就是第几个搜索这个点的
(这个LOW数组的解释我觉得相对是比较好的)