【连通图】无向图关节点和桥 Tarjan

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

const int N = 1e5, M = 1e5;
struct Edge {
    int v, next, idx;
    Edge(){}
    Edge(int _v, int _next, int _idx):
        v(_v), next(_next), idx(_idx){}
}e[M];
int low[N], dfn[N], deep, head[N], tot;
bool iscut[N], isbri[M];

void __init__()
{
    tot = deep = 0;
    memset(head, -1, sizeof(head));
    memset(iscut, 0, sizeof(iscut));
}

void add(int u, int v, int idx)
{
    e[tot++] = Edge(v, head[u], idx);
    head[u] = tot++;
}

int dfs(int u, int fa)
{
    int lowu = dfn[u] = ++deep;
    int cnt = 0;
    for(int i = head[u]; ~i; i = e[i].next) {
        int v = e[i].v;
        if(!dfn[v]) {
            cnt++;
            int lowv = dfs(v, u);
            lowu = min(lowu, lowv);
            if(lowv >= dfn[u]) iscut[u] = true;
            if(lowv > dfn[u]) isbri[e[i].idx] = true;
            continue ;
        }
        if(dfn[v] < dfn[u] && v != fa)
            lowu = min(lowu, dfn[v]);
    }
    if(fa == -1 && cnt == 1) iscut[u] = false;
    return low[u] = lowu;
}

int main()
{
    __init__();
    return 0;
}

时间: 2024-10-26 12:15:50

【连通图】无向图关节点和桥 Tarjan的相关文章

【连通图】双连通模板 Tarjan

比起求无向图关节点的算法,只是多了一个栈,用来储存不存在关节点的所有边,遇到关节点之后弹出所有边进行储存 int dfs(int u, int fa) { int lowu = dfn[u] = ++deep; int son = 0; for(int i = head[u]; ~i; i = e[i].next) { int v = e[i].v; Pair p = Pair(u, v); if(!dfn[v]) { s.push(p); son++; int lowv = dfs(v, u)

c2java 第7篇 图的连通分量,关节点和桥

图的连通分量,关节点和桥 ==== 对于有向图,我们称其一个子图是强连通分量,是指任意两点u,v, 都有两条路径u到v和v到u. 对于连通无向图,我门称其一个子图是双连通分量,是指任意两点u,v,存在一个圈包含u,v.与无向图相关联的还有关节点x,是指去掉x,图不连通:桥(u,v)是指去掉这条边,图不连通. 求解算法的要义在于首先要理解: 树边-前向边-后向边-交叉边 "Consider what happens when a depth-first search is performed on

hdu 2242 无向图/求用桥一分为二后使俩个bcc点权值和之差最小并输出 /缩点+2次新图dfs

题意如标题所述, 先无向图缩点,统计出每个bcc权,建新图,然后一遍dfs生成树,标记出每个点(新图)以及其子孙的权值之和.这样之后就可以dfs2来枚举边(原图的桥),更新最小即可. 调试了半天!原来是建老图时候链式前向星和新图的vector<vector< int>>俩种存图搞乱了!!!不可原谅!哎!愚蠢!愚不可及!提交后1A. 后来百度之后,发现说是用树形dp,看了代码解法,竟然和我的是一样的算法..原来这种算法可以叫树形dp...的确有点dp味道..不过感觉不太浓.. 以后多

Tarjan求无向图割点、桥详解

tarjan算法--求无向图的割点和桥 一.基本概念 1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥无向连通图中,如果删除某边后,图变成不连通,则称该边为桥. 2.割点:无向连通图中,如果删除某点后,图变成不连通,则称该点为割点. 二:tarjan算法在求桥和割点中的应用 1.割点:1)当前节点为树根的时候,条件是"要有多余一棵子树"(如果这有一颗子树,去掉这个点也没有影响,如果有两颗子树,去掉这点,两颗子树就不连通了.) 2)

【关节点+桥】关节点和桥模板 Tarjan

#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1e5, M = 1e5; struct Edge { int v, next, idx; Edge(){} Edge(int _v, int _next, int _idx): v(_v), next(_next), idx(_idx){} }e[M]; int dfn[N], dee

[POJ3177]Redundant Paths(双连通图,割边,桥,重边)

题目链接:http://poj.org/problem?id=3177 和上一题一样,只是有重边. 如何解决重边的问题? 1.  构造图G时把重边也考虑进来,然后在划分边双连通分量时先把桥删去,再划分,其中桥的一端的割点归入当前正在划分的边双连通分量.这个处理比较麻烦: 2.  在输入图G的边时,若出现重边,则不把重边放入图G,然后在划分边双连通分量时依然用Low划分. 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓

POJ 3694——Network——————【连通图,LCA求桥】

Network Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3694 Description A network administrator manages a large network. The network consists of N computers and M links between pairs of compute

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

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

无向图求割顶与桥

无向图求割顶与桥 对于无向图G,如果删除某个点u后,连通分量数目增加,称u为图的关节点或割顶.对于连通图,割顶就是删除之后使图不再连通的点.如果删除边(u,v)一条边,就可以让连通图变成不连通的,那么边(u,v)是桥. 具体的概念和定义比较多,在刘汝佳<<训练指南>>P312-314页都有详细的介绍. 下面来写求无向图割顶和桥的DFS函数.我们令pre[i]表示第一次访问i点的时间戳,令low[i]表示i节点及其后代所能连回(通过反向边)的最早祖先的pre值. 下面的dfs函数返回