三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

城乡互动联盟网站建设信阳有什么推广平台

城乡互动联盟网站建设信阳有什么推广平台 城乡互动联盟网站建设,信阳有什么推广平台,苏州园区网站建设公司,上海哪家网站建设好Kosaraju是个很好听的名字// g 是原图,g2 是反图void dfs1(int u) {vis[u] = true;for (int v : g[u])if (!vis[v]) dfs1(v);s.push_back(u); }void dfs2(int u) {color[u] = sccCnt;for (int v : g2[u])if (!color[v…Kosaraju是个很好听的名字// g 是原图,g2 是反图void dfs1(int u) {vis[u] = true;for (int v : g[u])if (!vis[v]) dfs1(v);s.push_back(u); }void dfs2(int u) {color[u] = sccCnt;for (int v : g2[u])if (!color[v]) dfs2(v); }void kosaraju() {sccCnt = 0;for (int i = 1; i = n; ++i)if (!vis[i]) dfs1(i);for (int i = n; i = 1; --i)if (!color[s[i]]) {++sccCnt;dfs2(s[i]);} }这是 Kosaraju,码搬自 oiwiki。该算法依靠两次简单的 DFS 实现: 第一次 DFS,选取任意顶点作为起点,遍历所有未访问过的顶点,并在回溯之前给顶点编号,也就是后序遍历. 第二次 DFS,对于反向后的图,以标号最大的顶点作为起点开始 DFS.这样遍历到的顶点集合就是一个强连通分量.对于所有未访问过的结点,选取标号最大的,重复上述过程. 正确性证明:第一次 DFS,设有编号小的点 \(x\),标号大的点 \(y\)。有两种情况:要么 \(y\) 是 \(x\) 的祖先点,即 \(y\) 可以走到 \(x\);要么 \(y\) 走不到 \(x\),但 \(x\) 先遍历。\(y x\) 所以 \(y\) 不可能走到 \(x\)。 第二次 DFS,这次 DFS 从大搜到小,设从 \(y\) 开始搜,搜到了 \(x\),则由于是反图有 \(x \to y\),如果这对 \((x,y)\) 在第一次 DFS 属于第一种情况,则有 \(y \to x\),这就符合强连通分量了;如果属于第二种情况(假设),那么 \(x\) 比 \(y\) 先遍历,因此在遍历的时候一定会搜到 \(x\) 到 \(y\) 的路径,结果标号会 \(x y\),与定义矛盾。因此这样搜出来的一定是强连通分量。 感觉是一种很神奇的方法。
← 返回列表