无向图的割顶和桥

来源:互联网 发布:淘宝匡威官方旗舰店 编辑:程序博客网 时间:2024/04/28 06:36

定义:

1.对于无向图,如果删除某个点u后,连通分量的数目增加,称u为图的关节点或割点。对于连通图来说,删除割点后,图将变得不再连通。
2.设 low(u) 为u及其后代所能连回的最早的祖先的pre值,当u的后代只能连回u自己时,即 low[v]>pre[u],只需删除边 u>v,即可让图非连通了,满足这个条件的边称为桥,也就是我们不仅知道了u是割点,还知道了u>v是桥。

求无向图的所有割点方法:

1.尝试删除每个节点,然后dfs判断连通分量是否增加;
2.线性时间内求出所有割点;

相关定理:

1.在无向图的dfs树中,非根节点u是G的割点当且仅当u存在一个子节点v,使得v及其所有后代都没有反向边连回u的祖先。

代码:

1.无向图的dfs森林

int dfs(int u){    vis[u] = 1;    pre[u] = ++ord;    int d = G[u].size();    for(int i = 0;i < d;i++){        int v = G[u][i];        if(!vis[v]) dfs(v);    }    post[u] = ++ord;}

2.求low函数及所有割顶

bool low[N],iscut[N];int dfs(int u,int fa){    int lowu = pre[u] = ++ord;    int child = 0;    for(int i = 0;i < G[u].size();i ++){        int v = G[u][i];        if(!pre[v]){            child++;            int lowv = dfs(v,u);            lowu = min(lowu,lowv);//利用后代的low函数更新u的low函数            if(lowv >= pre[u]){                iscut[u] = 1;            }        }        else if(pre[v] < pre[u] && v != fa){            lowu = min(lowu,pre[v]);  // 利用反向边更新u的low函数        }    }    if(fa < 0 && child == 1) iscut[u] = 0;    return low[u] = lowu;}
0 1