版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。

...

提示

下图中有几个连通分量?

draw.io Diagram
borderfalse
diagramName连通分量1
simpleViewertrue
width
linksauto
tbstyletop
diagramDisplayName
lboxfalse
diagramWidth432
revision1
答案:有3个连通分量,如下图所示,通过不同颜色标记:

答案:

展开

有3个连通分量,如下图所示,通过不同颜色标记:

draw.io Diagram
borderfalse
diagramName连通分量2
simpleViewertrue
width
linksauto
tbstyletop
diagramDisplayName
lboxfalse
diagramWidth431
revision1


强连通图:在有向图中,如果图中任意两个节点从uv都有路径,且从vu也有路径,则称图G为强连通图

...

提示

下图中有几个强连通分量?

draw.io Diagram
borderfalse
diagramName强连通分量1
simpleViewertrue
width
linksauto
tbstyletop
diagramDisplayName
lboxfalse
diagramWidth262
revision1

答案:

展开
答案:有3个强连通分量,如下图所示,通过不同颜色标记:

有3个强连通分量,如下图所示,通过不同颜色标记:

draw.io Diagram
borderfalse
diagramName强连通分量2
simpleViewertrue
width
linksauto
tbstyletop
diagramDisplayName
lboxfalse
diagramWidth261
revision1


强连通分量求解算法-Tarjan算法模板:

代码块
#define MAXN 1005

int G[MAXN][MAXN]; // 邻接矩阵
int n;             // 顶点数,顶点编号从0开始

int timestamp;  // 时间戳
int dfn[MAXN];  // 第一次遍历到达u的时间戳,至少为1,为0表示u还未被访问过
int low[MAXN];  // 从顶点u开始的DFS遍历能到达的最小时间戳

stack<int> stk;
bool in_stk[MAXN]; // 记录顶点u是否在栈中

int scc_cnt;  // 记录强连通分量的个数,也用于给强连通分量编号
int id[MAXN]; // 记录顶点所属的强连通分量编号

void tarjan_dfs(int u) {
    dfn[u] = low[u] = ++timestamp; // 第一次遍历到u,初始化当前点的时间戳
    stk.push(u);
    in_stk[u] = true;
    for(int i = 0; i < n; i++) { // 遍历所有u能到的邻接点
        if(G[u][i]) {
            if(dfn[i] == 0) { // 如果这个点还没被访问过
                tarjan_dfs(i); // 遍历邻接点
                low[u] = min(low[u], low[i]); // 子结点能到的最小时间戳u能也到
            } else if(in_stk[i]) { // 如果这个点还在栈中,说明这个点比u点先访问到,它的时间戳也应该更早
                low[u] = min(low[u], lowdfn[i]); // 用层级更高的点的时间戳更新u的low值
            }
        }
    }
    if(dfn[u] = low[u]) { // 如果u为某个强连通分量的最高点,则可以输出这个强连通分量
        scc_cnt++; // 连通分量数加1
        int tmp;
        do {
            tmp = stk.top();
            stk.pop();
            in_stk[tmp] = false;
            id[tmp] = scc_cnt; // 标记这个点属于哪个强连通分量
        } while(tmp != u);
    }
}

void tarjan() {
    for(int i = 0; i < n; i++) { // 对所有点进行强连通分量计算
        if(dfn[i] == 0) {
            tarjan_dfs(i);
        }
    }
}

...