割顶是去掉后让无向图不再连通的点。
在一棵DFS树中,
1.根root是割顶 ------------- 它至少有两个儿子
2.其他点v是割顶 ------------- 它有一个儿子u, 从u或者u的后代出发没有指向v祖先(不含v)的B边, 则删除v以后u和v的父亲不连通, 故为割顶。
桥(割边)是去掉后让无向图不再连通的边。
//下面的算法找到一条桥就截止了,这里可以用来判断他有没有桥
/*==================================================*\
| 无向图找桥
| INIT: edge[][]邻接矩阵;vis[],pre[],anc[],bridge 置0;
| CALL: dfs(0, -1, 1, n);
\*==================================================*/
int bridge, edge[V][V], anc[V], pre[V], vis[V];
//vis[i] 0--尚未访问 1--正在访问 2--已经访问结束
//anc[i] 该点能到达的最小序号
//pre[i] 该点的序号
void dfs(int cur, int father, int dep, int n) { // vertex: 0 ~ n-1
if (bridge)//已经找到桥了
return;
vis[cur] = 1;//正在访问
pre[cur] = anc[cur] = dep;
for (int i = 0; i < n; ++i)
if (edge[cur][i]) {//有一条边cur-->i
if (i != father && 1 == vis[i]) {
if (pre[i] < anc[cur])
anc[cur] = pre[i]; //这是一条回边
}
if (0 == vis[i]) { //这是一条树边
dfs(i, cur, dep + 1, n);
if (bridge)
return;
if (anc[i] < anc[cur])
anc[cur] = anc[i];//更新该点能到达的最小值
if (anc[i] > pre[cur]) {
bridge = 1;
cout<<cur<<" "<<i<<endl;
return;
}
}
}
vis[cur] = 2;
}