Tarjan 割点割边【模板】

 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdio>
 4
 5 using namespace std;
 6
 7 const int N(100000+15);
 8 int n,m,u,v;
 9 int head[N],sumedge;
10 struct Edge
11 {
12     int to,next;
13     Edge(int to=0,int next=0) :
14         to(to),next(next){}
15 }edge[N<<1];
16
17 void ins(int from,int to)
18 {
19     edge[++sumedge]=Edge(to,head[from]);
20     head[from]=sumedge;
21 }
22
23 int dfn[N],low[N],tim;
24 int cutpoint[N],cutedge[N],sum;
25
26 void DFS(int now,int pre)
27 {
28     low[now]=dfn[now]=++tim;
29     int sumtredge=0,if_cutpoint=0;
30     for(int i=head[now];i!=-1;i=edge[i].next)
31         if((i^1)!=pre)
32         {
33             int go=edge[i].to;
34             if(!dfn[go])
35             {
36                 sumtredge++;
37                 DFS(go,i);
38                 if(low[go]>=dfn[now]) if_cutpoint=1;
39                 if(low[go]>dfn[now]) cutedge[i>>1]=true;
40                 low[now]=min(low[now],low[go]);
41             }
42             else low[now]=min(low[now],dfn[go]);
43           }
44     if(pre==-1)
45     {
46         if(sumtredge>1)  cutpoint[now]=true;
47     }
48     else if(if_cutpoint) cutpoint[now]=true;
49 }
50
51 int main()
52 {
53     /*freopen("made.txt","r",stdin);
54     freopen("myout.txt","w",stdout);*/
55
56     scanf("%d%d",&n,&m);
57     sumedge=-1; //使边之间更有关系
58     memset(head,-1,sizeof(head));
59     for(int i=1;i<=m;i++)
60     {
61         scanf("%d%d",&u,&v);
62         ins(u,v);
63         ins(v,u);
64     }
65     for(int i=1;i<=n;i++)
66         if(!dfn[i]) DFS(i,-1);
67     for(int i=1;i<=n;i++)
68         if(cutpoint[i]) printf("%d ",i);
69     printf("\n");
70     for(int i=0;i<sumedge;i++)
71         if(cutedge[i]) printf("%d ",i);
72     return 0;
73 }
时间: 2024-10-27 01:59:33

Tarjan 割点割边【模板】的相关文章

Tarjan&amp;割点&amp;割边&amp;点双&amp;边双&amp;缩点

文末有福利. Tarjan是通过搜索树和压栈完成的,维护两个东西:dfn[i](时间戳).low[i](通过搜索树外的边i(返祖边),节点能到达的最小节点的时间戳). 跑完Tarjan,缩点,可以得到DAG图(有向无环图),可以再建图或统计入度出度. 在有向图中,可以找强连通分量SCC(极大强联通子图)(任意两点可以互达): 多维护一个vis[i]表示在不在栈中. 1 void tarjan_(int u) 2 { 3 stack[++tp]=u; 4 dfn[u]=low[u]=++num;

求割点 割边 Tarjan

附上一般讲得不错的博客 https://blog.csdn.net/lw277232240/article/details/73251092 https://www.cnblogs.com/collectionne/p/6847240.html https://blog.csdn.net/zhn_666/article/details/77971619 然后附上模板题:              https://vjudge.net/problem/HihoCoder-1183 裸题,直接要你输

【学习整理】Tarjan:强连通分量+割点+割边

Tarjan求强连通分量 在一个有向图中,如果某两点间都有互相到达的路径,那么称中两个点强联通,如果任意两点都强联通,那么称这个图为强联通图:一个有向图的极大强联通子图称为强联通分量.   算法可以在 的时间内求出一个图的所有强联通分量. 表示进入结点 的时间 表示从 所能追溯到的栈中点的最早时间 如果某个点 已经在栈中则更新  否则对 进行回溯,并在回溯后更新  #include<iostream> #include<cstdlib> #include<cstdio>

tarjan求割边割点

tarjan求割边割点 内容及代码来自http://m.blog.csdn.net/article/details?id=51984469 割边:在连通图中,删除了连通图的某条边后,图不再连通.这样的边被称为割边,也叫做桥.割点:在连通图中,删除了连通图的某个点以及与这个点相连的边后,图不再连通.这样的点被称为割点.DFS搜索树:用DFS对图进行遍历时,按照遍历次序的不同,我们可以得到一棵DFS搜索树. 树边:在搜索树中的蓝色线所示,可理解为在DFS过程中访问未访问节点时所经过的边,也称为父子边

Tarjan算法与割点割边

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

割点算法模板(Cut-vertex)

下面是求割點的模板,還有cut_vertex_num[]數組(array)記錄了哪些是割點 Int cut_vertex_num[]; void dfs(int cur,int pa) { int child=0,flag=0,i; low[cur]=dfn[cur]=++depth; for(i=0;i<adj[cur].size();i++) { int next=adj[cur][i]; if(!dfn[next]) //若未访问过 { child++; dfs(next,cur); lo

{part2}DFN+LOW(tarjan)割边

首先非树边肯定不是割边,因为去掉它DFS树不受影响,只要还能生成一棵DFS树那么图就是连通的. 然后割掉一条树边只可能造成一个点与它的父亲不连通. 那好办,也就是说这个以这个点为根的子树就是上面所说的满足条件的子树,也就是它没有返祖边,不过要注意的是,这里的low被重定义为每个点沿着除了父边之外的所有边能访问到的最小的dfn值,请结合割点割边的含义以及上面加粗的字体理解这句话,差别其实就在于x到父亲可能会有重边. 其他的都一样,核心还是判断x是否是这样的一棵子树. 直接上例题: 天凯是苏联的总书

ZOJ 1588 Burning Bridges (tarjan求割边)

题目链接 题意 : N个点M条边,允许有重边,让你求出割边的数目以及每条割边的编号(编号是输入顺序从1到M). 思路 :tarjan求割边,对于除重边以为中生成树的边(u,v),若满足dfn[u] < low[v],则边(u,v)是割边. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace st

hdu1269 Tarjan强连通分量 模板(转)

#include<stdio.h> #include<iostream> #include<vector> using namespace std; const int maxn=10010; vector<int>g[maxn]; int Bcnt; int Top; int Index; int low[maxn],dfn[maxn]; int belong[maxn],stack[maxn]; int instack[maxn]; void Init_