美文网首页
Tarjan算法求割点,桥

Tarjan算法求割点,桥

作者: Gitfan | 来源:发表于2017-08-04 22:20 被阅读0次

下面介绍中无向图中割点和桥的概念:
割点:一个结点称为割点(或者割顶)当且仅当去掉该节点极其相关的边之后的子图不连通。
:一条边称为桥(或者割边)当且仅当去掉该边之后的子图不连通。
首先我们考虑一个连通图(非连通图可以分别考虑连通块),我们从任意一个起点开始进行深度优先搜索,可以得到一棵树,并且这棵树中所有结点的子树之间不存在边,即没有跨越两棵子树的边(考虑一下,如果存在,那么与深度优先搜索树的定义互相矛盾)。于是有如下定理:
在无向连通图G中,
1、根结点u为割顶当且仅当它有两个或者多个子结点;
2、非根结点u为割顶当且仅当u存在子结点v,使得v极其所有后代都没有反向边可以连回u的祖先(连回u不算)
在Tarjan算法里面,有两个时间戳非常重要,一个是dfn,意为深度优先数,即代表访问顺序;一个是low,意为通过反向边能到达的最小dfn。于是,上述定理中第二个条件(非根结点)可以简单地写成low[v]>=dfn[u]。

Network
割点

#include <cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int MAXN=110;
vector<int> graph[MAXN];
int dfn[MAXN];
int low[MAXN];
int dfn_clock;
int isCut[MAXN];
int tarjan(int u,int fa)
{
    int lowu=dfn[u]=++dfn_clock;
    int child=0;
    for(int i=0;i<graph[u].size();i++)
    {
        int v=graph[u][i];
        if(dfn[v]==0)
        {
            child++;
            int lowv=tarjan(v,u);
            lowu=min(lowv,lowu);
            if(lowv>=dfn[u])
            {
                isCut[u]=1;
            }
        }
        else if(dfn[u]>dfn[v]&&v!=fa)
        {
            lowu=min(dfn[v],lowu);
        }
    }
    if(fa<0&&child==1) isCut[u]=0;
    low[u]=lowu;
    return lowu;
}
int main()
{
    int n;
    int u,v;
    char c;
    while(scanf("%d",&n)!=EOF&&n)
    {
        memset(graph,0,sizeof(graph));
        dfn_clock=0;
        while(true)
        {
            scanf("%d",&u);
            if(u==0) break;
            getchar();
            while(true)
            {
                scanf("%d",&v);
                graph[u].push_back(v);
                graph[v].push_back(u);
                c=getchar();
                if(c=='\n') break;
            }
        }
        memset(dfn,0,sizeof(dfn));
        memset(isCut,0,sizeof(isCut));
        tarjan(1,-1);
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            if(isCut[i]) sum++;
        }
        printf("%d\n",sum);
    }
    return 0;
}

桥:
桥的求法其实也是类似的,它的求法可以看成是割顶的一种特殊情况,当结点u的子结点v的后代通过反向边只能连回v,那么删除这条边(u, v)就可以使得图G非连通了。用Tarjan算法里面的时间戳表示这个条件,就是low[v]>dfn[u]。

int n,stamp,dfn[1005],low[1005];
int cnt,ansx[10005],ansy[10005];
vector<int> vec[1005];
int rank[1005];
void addAns(int x,int y)
{
    if(x>y)
        swap(x,y);
    ansx[cnt]=x, ansy[cnt]=y;
    cnt++;
}
void tarjan(int index,int fa)
{
    int tmp;
    dfn[index]=low[index]=++stamp;
    for(int i=0;i<vec[index].size();i++)
    {
        tmp=vec[index][i];
        if(!dfn[tmp])
        {
            tarjan(tmp,index);
            low[index]=min(low[index],low[tmp]);
            if(low[tmp]>dfn[index])
                addAns(index,tmp);
        }
        else if(dfn[tmp]<dfn[index] && tmp!=fa)
        {
            low[index]=min(low[index],dfn[tmp]);
        }
    }
}

相关文章

  • Tarjan算法求割点,桥

    下面介绍中无向图中割点和桥的概念:割点:一个结点称为割点(或者割顶)当且仅当去掉该节点极其相关的边之后的子图不连通...

  • Tarjan算法求割点和桥

    定义: 割点:在一个无向连通图中,若删除某点后,图变成不连通,则称该点为该图的割点。 桥:在一个无向连通图中,若删...

  • 连通图

    Strongly Connected Componenet 割点(tarjan): 题目链接:Network(求割...

  • 无向图求割点和割边——Tarjan算法

    无向图中求割点集和割边集——Tarjan算法割点和割边定义在一个无向图中,如果删除了某个顶点及与之相连的所有边,产...

  • 图论-----求割点

    求无向连通图割点(java)-------Tarjan算法 在无向连通图中,如果将其中一个点以及所有连接该点的边去...

  • 图论(1)-tarjan算法求强联通分量,割点,桥

    在LC里面的图论题,一般还是非常基础的,BFS,或者Dijkstra 为主。造成其实有很多经典的图论算法运用的不多...

  • tarjan算法

    tarjan算法前提 一个关于图的联通性的神奇算法。基于DFS(深度搜索)算法,深度优先搜索一张有向图。!注意!是...

  • 图的桥和割点

    内容概要: 图中的桥 图的DFS遍历树和BFS遍历树及其与寻桥算法的关系 图的割点 DFS和BFS的对比小结 桥(...

  • tarjan-LCA最近公共祖先离线算法

    在一棵树上查询任意两个点的最近公共祖先,或求最短距离的离线算法tarjan,基于dfs遍历和并查集,在查询时倍增直...

  • Tarjan算法求强连通分量

    首先先要明确概念:强连通图意为在该图中任意两点间都能够相互到达,而强连通分量即为一个强连通图中的子图,如图中{1,...

网友评论

      本文标题:Tarjan算法求割点,桥

      本文链接:https://www.haomeiwen.com/subject/pkvplxtx.html