Tarjan算法求解无向连通图的割点的模板

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn=1111;//有多少个结点
vector<int>G[maxn];
int visited[maxn];//标记该节点有没有访问过
int node,edge;//顶点数目
int tmpdfn;//dfs过程中记录当前的深度优先搜索序数
int dfn[maxn];//记录每个顶点的深度优先搜索序数
int low[maxn];//每个顶点的low值,根据该值来判断是否是关节点
int son;//根结点的有多少个孩子,如果大于等于2,则根结点为关节点
int subnets[maxn];//记录每个结点(去掉该结点后)的连通分量的个数

void init()
{
    for(int i=0;i<maxn;i++) G[i].clear();
    low[1]=dfn[1]=1;
    tmpdfn=1;son=0;
    memset(visited,0,sizeof(visited));
    visited[1]=1;
    memset(subnets,0,sizeof(subnets));
}

void dfs(int u)
{
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if(!visited[v])
        {
            visited[v]=1;
            tmpdfn++; dfn[v]=low[v]=tmpdfn;
            dfs(v);
            low[u]=min(low[u],low[v]);
            if(low[v]>=dfn[u])
            {
                if(u!=1) subnets[u]++;
                if(u==1) son++;
            }
        }
        else low[u]=min(low[u],dfn[v]);
    }
}

int main()
{
    scanf("%d%d",&node,&edge);//输入节点数量和边的数量
    init();//初始化
    for(int i=1;i<=edge;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);

        //无向图建边
        G[u].push_back(v);
        G[v].push_back(u);

    }

    //求解割点
    dfs(1);

    //计算根节点
    if(son>1) subnets[1]=son-1;
    for(int i=1;i<=node;i++)
        if(subnets[i])
            printf("%d号节点是割点,删除之后有%d个连通分量\n",i,subnets[i]+1);

    return 0;
}
时间: 2024-08-29 05:41:20

Tarjan算法求解无向连通图的割点的模板的相关文章

TarJan 算法求解有向连通图强连通分量

[有向图强连通分量] 在有向图G中,如果两个 顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 大体来说有3中算法Kosaraju,Trajan,Gabow这三种!后续文章中将相继

求无向连通图的割点

求一个连通图的割点,割点的定义是,如果除去此节点和与其相关的边,图不再连通. 连通图的定义:如果图中任意两点都是连通的,那么图被称作连通图.如果此图是有向图,则称为强连通图(注意:需要双向都有路径) 割点:在无向连通图中,删除一个顶点v及其相连的边后,原图从一个连通分量变成了两个或多个连通分量,则称顶点v为割点,同时也称关节点 (Articulation Point).多连通图没有割点,若在多连通图上至少删去k个顶点才能破坏图的连通性,则称此图为k连通图.貌似有向连通图没有割点这个说法. 连通分

有向图强连通分支的Tarjan算法讲解 + HDU 1269 连通图 Tarjan 结题报告

题目很简单就拿着这道题简单说说 有向图强连通分支的Tarjan算法 有向图强连通分支的Tarjan算法伪代码如下:void Tarjan(u) {dfn[u]=low[u]=++index//进行DFS,每发现一个新的点就对这个点打上时间戳,所以先找到的点时间戳越早,dfn[U]表示最早发现u的时间,low[u]表示u能到达的最早的时间戳.stack.push(u)//将U压入栈中for each (u, v) in E {if (v is not visted)//如果V点没有经历过DFS,则

无重边无向连通图的割点和桥

1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<algorithm> 5 using namespace std; 6 vector<vector<int> > g; 7 int dfn[11000];//节点在dfs过程中的访问序号(也可以叫做开始时间) 8 int low[11000];//节点的子树中能够通过非父子边追溯到的最早的节点的df

Tarjan算法与割点割边

目录 Tarjan算法与无向图的连通性 1:基础概念 2:Tarjan判断割点 3:Tarjan判断割边 Tarjan算法与无向图的连通性 1:基础概念 在说Tarjan算法求解无向图的连通性之前,先来说几个概念: <1. 时间戳:在图的深度优先遍历中,按照每一个结点第一次被访问到的时间顺序,依次给予N个结点1~N的整数边集,该标记就被计位"时间戳",计做 \(dfn[x]\). <2. 搜索树:任选一个结点深度优先遍历,每个点只访问一次.产生递归的边构成的树为搜索树. &

(转载)LCA问题的Tarjan算法

转载自:Click Here LCA问题(Lowest Common Ancestors,最近公共祖先问题),是指给定一棵有根树T,给出若干个查询LCA(u, v)(通常查询数量较大),每次求树T中两个顶点u和v的最近公共祖先,即找一个节点,同时是u和v的祖先,并且深度尽可能大(尽可能远离树根).LCA问题有很多解法:线段树.Tarjan算法.跳表.RMQ与LCA互相转化等.本文主要讲解Tarjan算法的原理及详细实现. 一 LCA问题 LCA问题的一般形式:给定一棵有根树,给出若干个查询,每个

HDU ACM 1269迷宫城堡-&gt;有向强连通分量(tarjan算法实践)

分析:本题判断一个图是否是有向强连通分量,这里使用tarjan算法求解. #include<iostream> #include<vector> #include<stack> using namespace std; vector<int> map[10002]; stack<int> tarjan_stack; int low[10002]; int dfn[10002]; bool vis[10002]; int cnt,pos; void

Tarjan算法:求解图的割点与桥(割边)

简介: 割边和割点的定义仅限于无向图中.我们可以通过定义以蛮力方式求解出无向图的所有割点和割边,但这样的求解方式效率低.Tarjan提出了一种快速求解的方式,通过一次DFS就求解出图中所有的割点和割边. 欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 割点与桥(割边)的定义 在无向图中才有割边和割点的定义 割点:无向连通图中,去掉一个顶点及和它相邻的所有边,图中的连通分量数增加,则该顶点称为割点. 桥(割边):无向联通图中,去

『Tarjan算法 无向图的割点与割边』

无向图的割点与割边 定义:给定无相连通图\(G=(V,E)\) 若对于\(x \in V\),从图中删去节点\(x\)以及所有与\(x\)关联的边后,\(G\)分裂为两个或以上不连通的子图,则称\(x\)为\(G\)的割点. 若对于\(e \in E\),从图中删去边\(e\)之后,\(G\)分裂为两个不连通的子图,则称\(e\)为\(G\)的割边. 对于很多图上问题来说,这两个概念是很重要的.我们将探究如何求解无向图的割点与割边. 预备知识 时间戳 图在深度优先遍历的过程中,按照每一个节点第一