首页 > 其他分享 >tarjan

tarjan

时间:2024-04-09 16:11:40浏览次数:18  
标签:tarjan min int dfs dfn low id

定义:删除这条边后连通块数量加1

思考先暴力搜出一棵树,然后对于每一条非树边都会构成一个环,这个环上的边就不可能是桥了(拿样例来看)
image
\(1 \rightarrow 2\) 和 \(5 \rightarrow 6\) 就是桥
假如用 \(lca\) 来维护加一个树上差分码量就有点惊人了
考虑优化
如果搜树的顺序改为 \(dfs\) 序,那么非树边就一定是父亲指向儿子,那么就不需要 \(lca\) 了
还有一种做法叫 \(tarjan\)
记 \(low_u\) 为 \(dfs\) 树上子树 \(u\) 内所有节点中,仅通过非树边能够抵达的结点之中 \(dfs\) 序最小者
那么如果是树边 \(low_u = min(low_u, low_v)\),如果不是树边 \(low_u = min(low_u, dfn_v)\)
code:

void dfs(int u, int f) {
  dfn[u] = low[u] = ++dcnt;
  for (auto e : g[u]) {
    if (e.id == f) {
      continue;
    }
    int v = e.v, id = e.id;
    if (!dfn[v]) {
      dfs(v, id);
      low[u] = min(low[u], low[v]);
    }
    else low[u] = min(low[u], dfn[v]);
  }
  if (f != 0 && dfn[u] == low[u]) {
    ans.push_back(ans);
  }
}

割点

定义:删除这个点后连通块数量加1

首先和桥一样的找环做法就 \(pass\) 掉了,数据:
image
3为割点
方法:
我们对于 \(u\) 的所有树上结点遍历一遍
如果有某个 \(low_v >= dfn_u\) 说明如果 \(u\) 没了,那么 \(v\) 就会单独成为一个连通块,\(u\) 就是割点
注意事项:
1.叶子节点永远不是
2.根节点要判树边的数量是否 \(>1\)
code:

void dfs(int u, int f) {
  dfn[u] = low[u] = ++dcnt;
  for (auto e : g[u]) {
    if (e.id == f) {
      continue;
    }
    int v = e.v, id = e.id;
    if (!dfn[v]) {
      dfs(v, id);
      low[u] = min(low[u], low[v]);
      cnt[u]++;
      if (cnt[u] > 1 && f == 0) {
        vis[u] = true;
      }
      if (low[e.v] >= dfn[u] && f != 0) {
        vis[u] = true;
      }
    }
    else low[u] = min(low[u], dfn[v]);
  }
}

边双连通分量

直接删去没条桥,搜连通块

标签:tarjan,min,int,dfs,dfn,low,id
From: https://www.cnblogs.com/libohan/p/18124094

相关文章

  • Tarjan板子
    Tarjan画图必备强连通分量(有向边)常见题建好有向图找强连通分量,同时记录每个强连通分量中节点的个数找节点个数最小的强连通分量点击查看代码structEdge{ intto,next;}edge[N];voidadd(intu,intv){ edge[++cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt;......
  • Tarjan 算法——图论学习笔记
    Part.1引入在图论问题中,我们经常去研究一些连通性问题,比如:有向图的联通性:传递闭包——Floyd算法;有向图连通性的对称性:强联通分量(SCC)——Tarjan算法缩点;无向图的联通性:并查集;无向图的关键边:桥(割边)、边双——Tarjan算法缩点;无向图的关键点:割点、点双——Tarjan建立圆方......
  • 2024.3.23 笔记(Tarjan)
    P3469[POI2008]BLO-Blockade根据割点的定义,若节点\(i\)不是割点,则把节点\(i\)关联的所有边去掉之后,只有\(i\)与其他\(n-1\)个节点不连通,而其他\(n-1\)个节点之间是连通的。注意:题目求的是有序点对,即\((x,y)\)和\((y,x)\)算不同的点对,故此时答案是\(2*(n......
  • AcWing 1171. 距离 Tarjan算法离线求LCA
    题目输入样例1:22121001221输出样例1: 100100输入样例2:32121031151232输出样例2: 1025LCA算法:LCA(LeastCommonAncestors)最近公共祖先Tarjan求LCA是一种离线的算法,也就是说它一遍求出所有需要求的点的LCA,而不是需要求哪两个点再去求......
  • Tarjan整理
    求强连通分量个数#include<iostream>#include<cstdio>#include<stack>usingnamespacestd;structsss{ intt,ne;}e[1000005];inth[1000005],cnt;voidadd(intu,intv){ e[++cnt].ne=h[u]; e[cnt].t=v; h[u]=cnt;}intdfn[1000005],......
  • tarjan模板
    信息传递题目描述tarjan模板点击查看代码voidtarjan(intx){ dfn[x]=low[x]=++num; stk.push(x); v[x]=1; for(inti=h[x];i;i=nxt[i]) { if(!dfn[to[i]]) { tarjan(to[i]); low[x]=min(low[x],low[to[i]]); } elseif(v[to[i]]) { low[x]=min(lo......
  • tarjan 各类板子集合
    tarjan大板子(非讲解):1、普通缩点DGAvoidtarjan(intx){ dfn[x]=low[x]=++cntp; q.push(x);v[x]=1; for(inti=head[x];i;i=bi[i].next){ intj=bi[i].to; if(!dfn[j]){ tarjan(j); low[x]=min(low[x],low[j]); } elseif(v[j])low[x]=min(low[x],dfn[j]); }......
  • tarjan模板
    因ppt太水遂有此文有向图求强连通分量点击查看代码voidtarjan(intx){ dfn[x]=low[x]=++num; stk.push(x); f[x]=1; for(inti=head[x];i;i=net[i]) { if(!dfn[to[i]]) { tarjan(to[i]); low[x]=min(low[x],low[to[i]]); } elseif(f[to[i]]) { l......
  • tarjan
    缩点有向图缩点(把一个强连通分量看成一个点),用于优化。树枝边:DFS时经过的边,即DFS搜索树上的边反祖边:也叫回边或后向边,与DFS方向相反,从某个结点指向其某个祖先的边横叉边:从某个结点指向搜索树中另一子树中的某结点的边,它主要是在搜索的时候遇到了一个已经访问过的结点,但......
  • Tarjan算法求SCC,缩点
    Tanjan算法可以在O(n+m)的时间内求出强连通分量,常数小,是个非常优秀的算法。算法实现过程:dfn[x]表示x的dfs生成树上的编号,代表着时间戳,low[x]表示从x结点出发,能够访问到最早的时间戳。<1>进入u时,盖上时间戳,结点入栈。<2>枚举该点的结点的时候,分为三种情况:(1)如果该点v没有访......