【模拟7.25】回家(tarjan V-DCC点双连通分量的求法及缩点 求割点)模板题
作为一道板子题放在第二题令人身心愉悦,不到一个小时码完连对拍都没打。
关于tarjan割点的注意事项:
1.在该板子中我们求的是V-DCC,而不是缩点,V-DCC最少有两个点组成,表示出掉一个块里的任意
一点及其连边,联通性不变,所以割点只是顺便标记上low[to]>=dfn[x]的点,在以后的操作中
将割点与联通块连边,所以最坏情况下所生点数(即原图为一条链)为2*n-2
边数的话如没有明确给出一般为点数的8倍。
******(这题80分,就是数组开小,没加快读)*******
2.我们在tarjan中每次分联通块时,while(top!=to),因为x可以属于多个联通块,所以我们
不能将其弹栈,但可以将其放进块中
3.else中low用dfn更新,因为不这样我们会将所有节点更新为1,这里不需要判断to是否为fa
因为2.中的判断条件有>=;
4.多测清空!!!!!!!!!!!!!!
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<string>
5 #include<algorithm>
6 #include<cmath>
7 #include<stack>
8 #include<map>
9 #include<queue>
10 #define ps push_back
11 #define MAXN 405101
12 #define ll long long
13 using namespace std;
14 int read()
15 {
16 char c=getchar();int x=0;
17 while(c<'0'||c>'9')
18 {
19 c=getchar();
20 }
21 while(c>='0'&&c<='9')
22 {
23 x=(x<<1)+(x<<3)+(c^48);
24 c=getchar();
25 }
26 return x;
27 }
28 int dfn[MAXN],low[MAXN],cut[MAXN],de;
29 int vis[MAXN];
30 int num_id,cnt;
31 int belong[MAXN];
32 vector<int>v[MAXN];
33 stack<int>q;
34 struct node{int to,n;}e1[MAXN*4],e2[MAXN*4];
35 int head1[MAXN],head2[MAXN];int tot1,tot2;
36 void add1(int u,int v)
37 {
38 e1[++tot1].to=v;e1[tot1].n=head1[u];head1[u]=tot1;
39 }
40 void add2(int u,int v)
41 {
42 e2[++tot2].to=v;e2[tot2].n=head2[u];head2[u]=tot2;
43 }
44 void tarjan(int x)
45 {
46 dfn[x]=low[x]=++de;vis[x]=1;q.push(x);
47 int ss=0;
48 for(int i=head1[x];i;i=e1[i].n)
49 {
50 int to=e1[i].to;
51 if(dfn[to]==0)
52 {
53 tarjan(to);
54 low[x]=min(low[x],low[to]);
55 if(low[to]>=dfn[x])
56 {
57 ss++;
58 if(x!=1||ss>1)
59 {
60 cut[x]=1;
61 }
62 cnt++;
63 int top=0;
64 do
65 {
66 top=q.top();q.pop();vis[to]=0;
67 v[cnt].ps(top);
68 }
69 while(to!=top);
70 v[cnt].ps(x);
71 }
72 }
73 else
74 low[x]=min(low[x],dfn[to]);
75 }
76 }
77 int n;
78 int cut_kuan[MAXN];
79 void init()
80 {
81 num_id=cnt;
82 for(int i=1;i<=n;++i)
83 {
84 if(cut[i]==1)
85 {
86 belong[i]=++num_id;
87 cut_kuan[num_id]=i;
88 }
89 }
90 for(int x=1;x<=cnt;++x)
91 {
92 for(int i=0;i<v[x].size();++i)
93 {
94 int now=v[x][i];
95 if(cut[now]==1)
96 {
97 add2(belong[now],x);
98 add2(x,belong[now]);
99 }
100 else
101 {
102 belong[now]=x;
103 }
104 }
105 }
106 }
107 bool bian[MAXN];int fa[MAXN];
108 void DFS(int x)
109 {
110 bian[x]=1;
111 for(int i=head2[x];i;i=e2[i].n)
112 {
113 int to=e2[i].to;
114 if(bian[to]==1)continue;
115 fa[to]=x;
116 DFS(to);
117 }
118 }
119 int ans[MAXN];
120 void find()
121 {
122 int x=belong[n];
123 while(fa[x]!=0)
124 {
125 x=fa[x];
126 if(cut_kuan[x]!=0&&x!=belong[1])
127 {
128 ans[++ans[0]]=cut_kuan[x];
129 }
130 }
131 }
132 int T,m;
133 int main()
134 {
135 scanf("%d",&T);
136 while(T--)
137 {
138 memset(head1,0,sizeof(head1));
139 memset(head2,0,sizeof(head2));
140 memset(cut,0,sizeof(cut));
141 memset(dfn,0,sizeof(dfn));
142 memset(low,0,sizeof(low));
143 memset(vis,0,sizeof(vis));
144 memset(belong,0,sizeof(belong));
145 memset(fa,0,sizeof(fa));
146 memset(bian,0,sizeof(bian));
147 memset(ans,0,sizeof(ans));
148 memset(cut_kuan,0,sizeof(cut_kuan));
149 tot1=0;tot2=0;
150 n=read();m=read();
151 for(int i=1;i<=m;++i)
152 {
153 int x,y;
154 //scanf("%d%d",&x,&y);
155 x=read();y=read();
156 add1(x,y);add1(y,x);
157 }
158 tarjan(1);
159 init();
160 DFS(belong[1]);
161 find();
162 printf("%d\n",ans[0]);
163 sort(ans+1,ans+ans[0]+1);
164 for(int i=1;i<=ans[0];++i)
165 {
166 printf("%d ",ans[i]);
167 }
168 cout<<endl;
169 for(int i=1;i<=cnt;++i)
170 {
171 v[i].clear();
172 }
173 cnt=0;de=0;num_id=0;
174 }
175 }
【模拟7.25】回家(tarjan V-DCC点双连通分量的求法及缩点 求割点)模板题的更多相关文章
- UVA 315 求割点 模板 Tarjan
D - D Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Status Pract ...
- Codeforces 962 /2错误 相间位置排列 堆模拟 X轴距离最小值 前向星点双连通分量求只存在在一个简单环中的边
A #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #def ...
- Tarjan算法初探(3):求割点与桥以及双连通分量
接上一节Tarjan算法初探(2):缩点 在此首先提出几个概念: 割点集合:一个无向连通图G 若删除它的一个点集 以及点集中所有点相连的边(任意一端在点集中)后 G中有点之间不再连通则称这个点集是它的 ...
- tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)
基本概念 给定无向连通图G = (V, E)割点:对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点割边(桥)若对于e∈E,从图中删去边e之后,G分 ...
- tarjan复习笔记 双连通分量,强连通分量
声明:图自行参考割点和桥QVQ 双连通分量 如果一个无向连通图\(G=(V,E)\)中不存在割点(相对于这个图),则称它为点双连通图 如果一个无向连通图\(G=(V,E)\)中不存在割边(相对于这个图 ...
- 『Tarjan算法 无向图的双联通分量』
无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...
- HZOI20190725 B 回家 tarjan
题目大意:https://www.cnblogs.com/Juve/articles/11226266.html 题解: 感觉挺水的,但考场上没打出来 题目翻译一下就是输出起点到终点必经的点 其实就是 ...
- hdu 2586 How far away ?(LCA - Tarjan算法 离线 模板题)
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- Tarjan 算法求割点、 割边、 强联通分量
Tarjan算法是一个基于dfs的搜索算法, 可以在O(N+M)的复杂度内求出图的割点.割边和强联通分量等信息. https://www.cnblogs.com/shadowland/p/587225 ...
随机推荐
- 找大于等于一个数的最小的2^n
最近看hashmap源码时,发现给定初始capacity计算threshold的过程很巧妙. 1 static final int tableSizeFor(int cap) { 2 int n = ...
- 【Docker】2. Docker的架构介绍、安装与卸载 (CentOS 7)
一.docker的基本组成 开局一张图. docker的组成: Client:客户端,可以通过它与docker服务进行交互.比如容器的构建.拉取.运行. DOCKER_HOST:就是docker服务. ...
- 图扑软件正式加入腾讯智维生态发展计划,智能 IDC 开启数字经济新征程
4 月 23 日,主题为<智汇科技,维新至善>的腾讯数据中心智维技术研讨会在深圳胜利召开,发布了腾讯智维 2.0 技术体系,深度揭秘了智维 2.0 新产品战略和技术规划.图扑软件(High ...
- Java方法区的理解
方法区逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩. 但对于HotSpotJVM而言,方法区还有一个别名叫做Non-Heap,目的就是要和堆分开 所以方法区看作是一块 ...
- 【Cocos2d-x】屏蔽Emoji并解决由于Emoji导致的崩溃问题
IOS的Emoji表情因为编码问题,在Android手机上无法正常显示,如果当前的cc.Label节点使用的是系统字,在系统字库中找不到对应编码的字符,会导致崩溃. 为了解决这个问题,又要兼顾新老版本 ...
- markerdown基础
标题 用#+空格 字体 加粗两边两个** 斜体两边* 斜体加粗三个* 引用 '>' 分割线 三个---或者三个*** 图片 ![截图]() 超链接 点击跳转到文章 []+() 列表 1 + 点+ ...
- Linux shell sed命令在文件行首行尾添加字符
昨天写一个脚本花了一天的2/3的时间,而且大部分时间都耗在了sed命令上,今天不总结一下都对不起昨天流逝的时间啊~~~ 用sed命令在行首或行尾添加字符的命令有以下几种: 假设处理的文本为test.f ...
- 性能工具 stream 最新版本5.10 The STREAM benchmark
官网下载最新性能工具 stream 最新版本5.10 https://github.com/jeffhammond/STREAM 官网下载最新性能工具 stream 最新版本5.10 http:/ ...
- Kubernetes 部署微服务电商平台(16)
一.概念 微服务就是很小的服务,小到一个服务只对应一个单一的功能,只做一件事.这个服务可以单独部署运行,服务之间可以通过RPC来相互交互,每个微服务都是由独立的小团队开发,测试,部署,上线,负责它的整 ...
- USB历代标准及接口发展
USB历代标准及接口发展 浊酒一杯家万里关注 2017.11.20 14:54:21字数 3,684阅读 2,514 文章转自中关村在线 1,多功能正反插 苹果让大众认识Type-C "Ty ...