连通性1 求无向图的low值

这是DFS系列的第一篇 。

首先给出一个重要的定理。该定理来自《算法导论》。

An undirected graph may entail some ambiguity in how we classify edges,
since (u, v) and (vu) are really the same edge. In such a case, we classify the edge according to whichever of (u, v) or (v, u) the search encounters first.

Introduction to Algorithm 3ed. edition p.610

Theorem 22.10
In a depth-first search of an undirected graph G, every edge of G is either a tree
edge or a back edge.

Proof Let (u, v) be an arbitrary edge of G, and suppose without loss of generality
that u.d < v.d. Then the search must discover and finish v before it finishes u
(while u is gray), since v is on u’s adjacency list. If the first time that the search
explores edge (u, v), it is in the direction from u to v, then v is undiscovered
(white) until that time, for otherwise the search would have explored this edge
already in the direction from v to u. Thus, (u, v) becomes a tree edge. If the
search explores (u, v) first in the direction from v to u, then (u, v) is a back edge,
since u is still gray at the time the edge is first explored.

low值大概是Robert Taryan在论文 Depth-first search and linear graph algorithms  SIAM J. Comput. Vol. 1, No. 2, June 1972给出的概念。

(p.150)"..., LOWPT(v) is the smallest vertex reachable from v by traversing zero or more tree arcs followed by at most one frond."

代码如下

 1 #define set0(a) memset(a, 0, sizeof(a))
 2 typedef vector<int> vi;
 3 vi G[MAX_N];
 4 int ts; //time stamp
 5 int dfn[MAX_N], low[MAX_N];
 6 void dfs(int u, int f){
 7     dfn[u]=low[u]=++ts;
 8     for(int i=0; i<G[u].size(); i++){
 9         int &v=G[u][i];
10         if(!dfn[v]){    //tree edge
11             dfs(v, u);
12             low[u]=min(low[u], low[v]);
13         }
14         else if(dfn[v]<dfn[u]&&v!=f){    //back edge
15             low[u]=min(low[u], dfn[v]);
16         }
17     }
18 }
19 void solve(int N){
20     set0(dfn);
21     ts=0;
22     for(int i=1; i<=N; i++)
23         if(!dfn[i]) dfs(i, i);
24 }
时间: 2024-10-07 03:54:38

连通性1 求无向图的low值的相关文章

【求无向图的桥,有重边】ZOJ - 2588 Burning Bridges

模板题——求割点与桥 题意,要使一个无向图不连通,输出必定要删掉的边的数量及其编号.求桥的裸题,可拿来练手. 套模板的时候注意本题两节点之间可能有多条边,而模板是不判重边的,所以直接套模板的话,会将重边也当做桥输出,因此要在判断桥的时候加一个判断,即当且仅当两点之间仅有一条边,且满足dfn[cur] < low[i],(cur, i)才是桥. 另外本题节点数为105,用邻接矩阵的话会内存超限,所以我用了了一个multiset存储边及其编号. 代码如下: 1 #include<cstdio>

Hdu 4738【tanjan求无向图的桥】

题目: 曹操在长江上建立了一些点,点之间有一些边连着.如果这些点构成的无向图变成了连通图,那么曹操就无敌了.刘备为了防止曹操变得无敌,就打算去摧毁连接曹操的点的桥.但是诸葛亮把所有炸弹都带走了,只留下一枚给刘备.所以刘备只能炸一条桥. 题目给出n,m.表示有n个点,m条桥. 接下来的m行每行给出a,b,c,表示a点和b点之间有一条桥,而且曹操派了c个人去守卫这条桥. 现在问刘备最少派多少人去炸桥. 如果无法使曹操的点成为多个连通图,则输出-1. 思路: 就是用tarjan算法算出桥的数量,再比较

求无向图最小割

先解释下名词的意思. 无向图的割:就是去掉一些边,使得原图不连通,最小割就是要去掉边的数量最小. 解决这个问题的常用办法就是Stoer-Wagner 算法: 先说下这个算法的步骤后面给出证明: 1.min=MAXINT,固定一个顶点P 2.从点P用类似prim的s算法扩展出"最大生成树",记录最后扩展的顶点和最后扩展的边 3.计算最后扩展到的顶点的切割值(即与此顶点相连的所有边权和),若比min小更新min 4.合并最后扩展的那条边的两个端点为一个顶点 5.转到2,合并N-1次后结束

洛谷P1141 //bfs求无向图的子连通块大小(多次询问)

http://www.luogu.org/problem/show?pid=1141 多询问题,求无向图的子连通块大小. 直接bfs,读一个搜一个,过60: 100%的点1,000,000个点,100,000次询问,显然是记忆化. 我很弱,最开始开了个数组记录每个点属于的连通块的第一个点的坐标,然后写了一堆,自己都烦. 后来问某大神,似拨开云雾见到了青天.用cnt记录连通块的" 名字 ". 学会了这一招,不代表过了. 我还是读一个点,如果访问过就输出,没访问就dfs,然后每dfs就循环

FZU 2090 旅行社的烦恼 floyd 求无向图最小环

题目链接:旅行社的烦恼 题意是求无向图的最小环,如果有的话,输出个数,并且输出权值. 刚刚补了一发floyd 动态规划原理,用了滑动数组的思想.所以,这个题就是floyd思想的变形.在k从1到n的过程中更新到k时,mindis数组中保存的是只经过1~k-1序号的点时,任意两个之间的最短路权值,这时候,选择点k作为环的起点即终点,在[1, k)之间选择两个点i, j 得到一个环,环的权值即为mindis[i][j] + dis[i][k] + dis[j][k].这样遍历得到的是就是所有的环,且环

SPF Tarjan算法求无向图割点(关节点)入门题

SPF 题目抽象,给出一个连通图的一些边,求关节点.以及每个关节点分出的连通分量的个数 邻接矩阵只要16ms,而邻接表却要32ms,  花费了大量的时间在加边上. //   time  16ms 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string&

hdu4612 连通性,求树的直径,加一边求最少桥

http://acm.hdu.edu.cn/showproblem.php?pid=4612 Problem Description N planets are connected by M bidirectional channels that allow instant transportation. It's always possible to travel between any two planets through these channels. If we can isolate

Uva 315 求无向图的割点的个数

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=251 A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to 

求无向图的割点和桥

/** * 求 无向图的割点和桥 * 可以找出割点和桥,求删掉每个点后增加的连通块. * 需要注意重边的处理,可以先用矩阵存,再转邻接表,或者进行判重 * 调用solve输出割点数,全局变量bridge记录边的个数 */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; const int maxn=1001