tarjan算法应用之割边和割点
来源:互联网 发布:js调用支付宝api接口 编辑:程序博客网 时间:2024/05/21 08:57
割边:在连通图中,删除了连通图的某条边后,图不再连通。这样的边被称为割边,也叫做桥。
割点:在连通图中,删除了连通图的某个点以及与这个点相连的边后,图不再连通。这样的点被称为割点。
DFS搜索树:用DFS对图进行遍历时,按照遍历次序的不同,我们可以得到一棵DFS搜索树。
树边:在搜索树中的蓝色线所示,可理解为在DFS过程中访问未访问节点时所经过的边,也称为父子边
回边:在搜索树中的橙色线所示,可理解为在DFS过程中遇到已访问节点时所经过的边,也称为返祖边、后向边
观察DFS搜索树,我们可以发现有两类节点可以成为割点。对根节点u,若其有两棵或两棵以上的子树,则该根结点u为割点;对非叶子节点u(非根节点),若其中的某棵子树的节点均没有指向u的祖先节点的回边,说明删除u之后,根结点与该棵子树的节点不再连通;则节点u为割点。对于根结点,显然很好处理;但是对于非叶子节点,怎么去判断有没有回边是一个值得深思的问题。我们用dfn[u]记录节点u在DFS过程中被遍历到的次序号,low[u]记录节点u或u的子树通过非父子边追溯到最早的祖先节点(即DFS次序号最小),那么low[u]的计算过程如下。
对于给的例子,其求出的dfn和low数组如下。
id 123456
dfn 123456
low 111444
可以发现,对于情况2,当(u,v)为树边且low[v]≥dfn[u]时,节点u才为割点。而当(u,v)为树边且low[v]>dfn[u]时,表示v节点只能通过该边(u,v)与u连通,那么(u,v)即为割边。tarjan算法的时间复杂度是O(n+m)的,非常快。
以hihoCoder1183为例给出代码:
#include<cstdio>#include<vector>#include<algorithm>using namespace std;int n,m,order=0;int low[20004],dfn[20004],father[20004],son[20004];//father:父结点 son:子结点个数 vector<int> cutpoint,edge[20004];vector< pair<int,int> > cutedge;void tarjan(int u){dfn[u]=low[u]=++order;bool flag=false;for (int i=0;i<edge[u].size();i++){int v=edge[u][i];if(!dfn[v]){son[u]++;father[v]=u; tarjan(v);if(low[v]>=dfn[u]) flag=true;//点u为割点 if(low[v]>dfn[u]) cutedge.push_back(make_pair(min(v,u),max(v,u)));//边v-u为割边 low[u]=min(low[u],low[v]);}else if(v!=father[u]) low[u]=min(low[u],dfn[v]);}//根节点若有两棵或两棵以上的子树则该为割点//非根节点若所有子树节点均没有指向u的祖先节点的回边则为割点if((father[u]==0&&son[u]>1)||(father[u]&&flag)) cutpoint.push_back(u);}int main(){scanf("%d%d",&n,&m);for (int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);edge[u].push_back(v),edge[v].push_back(u);}tarjan(1);sort(cutedge.begin(),cutedge.end());sort(cutpoint.begin(),cutpoint.end());if(0==cutpoint.size()) puts("Null");else{printf("%d",cutpoint[0]);for (int i=1;i<cutpoint.size();i++) printf(" %d",cutpoint[i]);puts("");}for(int i=0;i<cutedge.size();i++) printf("%d %d\n",cutedge[i].first,cutedge[i].second);}
- tarjan算法应用之割边和割点
- hihoCoder1183 tarjan算法应用之割边和割点
- tarjan算法之 割边,割点
- 割点和桥---Tarjan算法
- Tarjan算法求桥和割点
- 关于tarjan算法的一些理解(割边和割点)
- tarjan算法应用 割点 桥 双连通分量
- tarjan算法应用 割点 桥 双连通分量
- tarjan算法应用 割点 桥 双连通分量
- 割点和割边
- 割点和割边
- 求桥和割点的Tarjan算法
- Poj 1523 SPF(割点 + tarjan算法)
- tarjan最小割点算法模板
- poj2117 tarjan()+割点
- 【tarjan】【割点】
- tarjan 割点
- Tarjan算法求BCC(无向图连通块、割边、割点)
- Mac本不用连接网线,模拟ipv6网络环境
- 【杭电oj】1028 - Ignatius and the Princess III(母函数打表)
- C++ - 基础知识
- JavaScript中的字符串使用
- 获取系统磁盘类型信息以及判断是否是U盘
- tarjan算法应用之割边和割点
- Ext mvc 下的点击表格后弹出框中有下拉列表框 下拉列表框值如何显示
- Uncowed Forces(给方法,算总分)
- CodeSmith部署安装以及编写MySQL模板的时候无法获取description
- PHP APC缓存配置、使用详解
- JS 开发过程中遇到的常见问题
- Codeforces Problem 614B Gena's Code
- android之自定义viewGroup仿scrollView详解
- 树莓派使用gmaping建图