标签:遍历 tarjan top 动态 code 强连通 模拟 for 更新
int low[N],dfn[N],Stack[N],belong[N]; //最小下表,时间戳,一个用数组模拟的栈
//belong[x]表示x所属的强连通分量的编号
int idx,top;//,动态时间戳,栈顶
int scc; //scc表示强连通分量的个数
bool instack[N];//是否在栈里面
int num[N]; //num[x]表示第x个强连通分量内所包含的点的个数
//前向星
void addedge(int u,int v){
edge[tot].v = v;
edge[tot].nxt = head[u];
head[u] = tot++;
}
//模板
void tarjan(int u) {
int v;
low[u] = dfn[u] = ++idx;//记录时间戳
Stack[top++] = u;//入栈
instack[u] = 1;//标记u已经在栈中
for(int i = head[u]; i != -1; i = edge[i].nxt) {//遍历边
int v = edge[i].v;//v
if(!dfn[v]) {//第一次访问
tarjan(v);//dfs
if(low[u]>low[v]) low[u] = low[v];//记录low
}
else if(instack[v]&&low[u]>dfn[v]) low[u] = dfn[v];//已经在栈中的点,可以用来更新low标记
}
if(low[u]==dfn[u]) {//弹栈
scc++;//强连通个数加一
do {
v = Stack[--top];//弹栈
instack[v] = 0;//标记不在栈中
belong[v] = scc;//记录
num[scc]++;//点集大小加一
}
while(v!=u);//跑路
}
标签:遍历 tarjan top 动态 code 强连通 模拟 for 更新
原文地址:https://www.cnblogs.com/yesuweiYYYY/p/14692281.html