标签:
这是DFS系列的第二篇
In graph theory, a bridge, isthmus, cut-edge, or cut arc is an edgeof a graph whose deletion increases its number of connected components. Equivalently, an edge is a bridge if and only if it is not contained in any cycle. A graph is said to be bridgeless or isthmus-free if it contains no bridges.
割边 (cut edge)也称作桥(bridge)是删除后能使图的连通分量增加的边。
下面我们只考虑无向图。
考虑一个连通的无向图G,若它含有某条割边e(u, v),那么去掉这条边后,将得到2个连通图G‘, H‘,而不可能得到2个以上连通图,因为一条边最多能将2个连通图合为一个联通图。
下面介绍求无向图所有割边的Taryan算法(Taryan‘s Bridge-Finding Algorithm)
我们只考虑对无向连通图G求割边,若图G不连通那么就对G的各个连通分量求割边。
我们知道DFS一个无向图将其所有边分成两类,树边(tree edge)与回边(back edge)。显然地,割边只能是树边而绝不可能是回边。
考虑一条树边(u-->v)是割边的条件。这条件应当是在DFS树中,以v为根的子树(简称子树v)中的所有节点都没有连向u的祖先节点(包括u本身)的回边,也就是说子树v仅仅靠着边 (u,v) 和其他节点保持连通。
为了判断上述条件,我们在DFS过程中记录每个节点的dfn值与low值,树边 (u-->v)是割边的充要条件是 low[v]>dfn[u]。
struct edge{
int to, nt;
bool flag;
}E[MAX_E<<1];
int head[MAX_V];
int dfn[MAX_V], low[MAX_V];
int ts; //time stamp
void dfs(int u, int f){
dfs[u]=low[u]=++ts;
for(int i=head[i]; ~i; i=E[i].nt){
int &v=E[i].to;
if(!dfn[v]){ //tree edge
dfs(v, f);
low[u]=min(low[u], low[v]);
if(low[v]>dfn[u]){
e[i].flag=e[i^1].flag=true;
}
}
else if(v!=f&&dfn[v]<dfn[u]){ //back edge
low[u]=min(low[u], dfn[v]);
}
}
}
void solve(int N){
memset(dfn, 0, sizeof(dfn));
ts=0;
for(int i=1; i<=N; i++)
if(!dfn[i]) dfs(i, i);
}
标签:
原文地址:http://www.cnblogs.com/Patt/p/4713459.html