【模板】 Tarjan割点

题目描述

给出一个n个点,m条边的无向图,求图的割点。

输入输出格式

输入格式:

第一行输入n,m

下面m行每行输入x,y表示x到y有一条边

输出格式:

第一行输出割点个数

第二行按照节点编号从小到大输出节点,用空格隔开

输入输出样例

输入样例#1:

6 7
1 2
1 3
1 4
2 5
3 5
4 5
5 6

输出样例#1:

1
5

说明

n,m均为100000

tarjan 图不一定联通!!!

 1 #include<iostream>
 2 #include<cstdio>
 3 #define int long long
 4 using namespace std;
 5 const int MAXN=200010;
 6 struct XY{int to,pre;}e[MAXN*2];
 7 int las[MAXN],dfn[MAXN],low[MAXN],res[MAXN];
 8 int tim=0,sz=1,ans=0,n,m,x,y;
 9
10 void add(int a,int b){
11     e[++sz].to=b;e[sz].pre=las[a];las[a]=sz;
12     e[++sz].to=a;e[sz].pre=las[b];las[b]=sz;
13 }
14
15 void tarjan(int u,int fa){
16     int son=0,v;
17     dfn[u]=low[u]=++tim;
18     for (int i=las[u];i;i=e[i].pre)
19     if (!dfn[v=e[i].to]){
20         son++;tarjan(v,u);
21         low[u]=min(low[u],low[v]);
22         if (dfn[u]<=low[v]&&!res[u]) ans++,res[u]=1;
23     }else if (v!=fa) low[u]=min(low[u],dfn[v]);
24     if (fa==-1&&son==1) res[u]=0,ans--;
25 }
26
27 main(){
28     cin >>n>>m;
29     for (int i=1;i<=m;++i) scanf("%lld%lld",&x,&y),add(x,y);
30     for (int i=1;i<=n;++i) if (!dfn[i]) tarjan(i,-1);
31     cout <<ans<<endl;
32     for (int i=1;i<=n;++i) if (res[i]) printf("%lld ",i);
33     return 0;
34 }
时间: 2025-01-16 08:46:16

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

洛谷 P3388 【模板】割点(割顶)

P3388 [模板]割点(割顶) 题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照节点编号从小到大输出节点,用空格隔开 输入输出样例 输入样例#1: 6 7 1 2 1 3 1 4 2 5 3 5 4 5 5 6 输出样例#1: 1 5 说明 n,m均为100000 tarjan 图不一定联通!!!. 没错我以前就是不会,不服bb别solo #i

「模板」 割点

「模板」 割点 <题目链接> 不会点双导致的 APIO 完挂. 本应该联赛前学的东西,不及时学,就只有等到变回联赛选手后再学了吧. 以及,以后放弃链式前向星,存图一律指针邻接表. #include <algorithm> #include <cstdio> using std::min; const int MAXN=100010; bool cut[MAXN]; int n,m,DFN_num,ans,DFN[MAXN],low[MAXN]; struct Edge

【模板】割点

[模板]割点 割点集合:一个顶点集合V,删除该集合的所有定点以及与这些顶点相连的边后,原图不连通,就称集合V为割点集合 点连通度:最小割点集合中的顶点数 边连通度:最小割边集合中的边数 割点:割点集合中唯一的一个元素 Tarjan求缩点: 一个点为缩点的条件: 1.该点为根,搜索树中有大于1个子树 2.该点u不为根,存在儿子v,dfn[u]>low[v] 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio

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;

【模板】割点(割顶)(洛谷_3388)——tarjan

tarjan求割点,打了个模板题. #include<iostream> #include<cstdio> #include<vector> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num

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(

洛谷P3388 【模板】割点(割顶)

表示割点模板很难理解....但是呢,可以将整个图用深搜来一步步递归.. dfn[x]<=low[tmp] && x!=mr的点就++:完毕....PS:小心第一个节点...可能是一个二叉树结构 #include<iostream> #include<cstdio> #include<cstring> #define maxn 200100 using namespace std; int p[maxn],h[maxn],v[maxn],dfn[ma

luogu题解 P3388 【【模板】割点(割顶)】

外加定义:在一个无向图中,如果删掉点 x 后图的连通块数量增加,则称点 x 为图的割点. 外加图示 开始思路为割桥上的点为割点,后来证明的确正确. 不过可惜的是他的逆定理错了(gg了),不过数据很弱以至于得了90分. 如图所示 图中无割桥,但点3却是割点,貌似无法解决. (顺及客串my blog ,以及图论的必要工具 回归正题,另一种思路诞生了: 如果u点的子节点为v,v点他能返回的最老祖先比u点年轻或一样(即dfn[u]值<=low[v]),那么如果删去u点,那么v以下的点就会与v以上的点失去

洛谷 P3388 【模板】割点

题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照节点编号从小到大输出节点,用空格隔开 输入输出样例 输入样例#1: 6 7 1 2 1 3 1 4 2 5 3 5 4 5 5 6 输出样例#1: 1 5 说明 n,m均为100000 tarjan 图不一定联通!!! 屠龙宝刀点击就送 #include <algorithm> #include