void tarjan_dfs(int u) { dfn[u] = low[u] = ++idx; in_stack[u] = 1; stack_push_back(u); struct Edge *e = orig_edge[u]; while (e) { if (!dfn[e->v]) { tarjan_dfs(e->v); if (low[e->v] < low[u]) low[u] = low[e->v]; } else if (in_stack[e->v]) if (dfn[e->v] < low[u]) low[u] = dfn[e->v]; e = e->next; } if (dfn[u] == low[u]) { scc_cnt++; int v; do { v = stack_back(); stack_pop_back(); in_stack[v] = 0; scc_id[v] = scc_cnt; scc_size[scc_cnt]++; } while (v != u) ; } }
void tarjan_scc(int num_v = MAXV) { visiting = stack<int>(); memset(visited, 0, sizeof visited); cur_num = cur_comp = 0; for(int i = 0; i < num_v; ++i) if(!visited[i]) tarjan_dfs(i); }
void tarjan(int n) { idx = scc_cnt = 0; memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(scc_id, 0, sizeof(scc_id)); memset(scc_size, 0, sizeof(scc_size)); int i; for (i = 1; i <= n; i++) if (!dfn[i]) tarjan_dfs(i); }
int tarjan_dfs(int v) { lowest[v] = num[v] = cur_num++; visiting.push(v); visited[v] = 1; for(int i = last_edge[v]; i != -1; i = prev_edge[i]) { int w = adj[i]; if(visited[w] == 0) lowest[v] = min(lowest[v], tarjan_dfs(w)); else if(visited[w] == 1) lowest[v] = min(lowest[v], num[w]); } if(lowest[v] == num[v]) { int last = -1; while(last != v) { comp[last = visiting.top()] = cur_comp; visited[last] = 2; visiting.pop(); } ++cur_comp; } return lowest[v]; }