【模拟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 ...
随机推荐
- Hive企业级性能优化
Hive作为大数据平台举足轻重的框架,以其稳定性和简单易用性也成为当前构建企业级数据仓库时使用最多的框架之一. 但是如果我们只局限于会使用Hive,而不考虑性能问题,就难搭建出一个完美的数仓,所以Hi ...
- 如何解决 shell 脚本重复执行的问题
在开发过程中,经常会使用shell脚本去完成定时备份的任务,普遍的做法是通过系统的定时任务定时执行备份脚本 设想这样一种场景,本次备份时间到了,自动执行备份脚本,如果备份比较耗时的话,会一直持续到下一 ...
- 痞子衡嵌入式:在i.MXRT启动头FDCB里使能串行NOR Flash的Continuous read模式
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在FDCB里使能串行NOR Flash的Continuous read模式. 前面关于串行Flash传输时序的文章 <Fast R ...
- 自定义元类 __call__,__init__,__new__总结
只要对象能被调用 产生对象的类里必然有__call__方法 在调用类时,必定先触发type里的__call__ __call__下有: 1.产生对象的object.__new__ 2..被调用的类自己 ...
- FastDFS依赖无法导入
FastDFS依赖无法导入 fastdfs-client-java 导入爆红 <!-- FastDFS--> <dependency> <groupId>org.c ...
- Mybatis-plus在原有的select查询语句中动态追加查询条件
一.适用场景 1.使用了xml形式的mapper.2.不想在select查询中大量使用<if>标签来判断条件是否存在而加入条件. 二.步骤 1.自定义wrapper继承QueryWrapp ...
- 1小时快速搭建基于Azure Custom Vision和树莓派的鸟类分类和识别应用
1. 引言 最近在微软Learn平台学习Azure认知服务相关的内容,看到了一个有关"使用自定义视觉对濒危鸟类进行分类"的专题,该专题的主要内容就是使用 Azure Custom ...
- git合并代码到主分支
git合并login分支到master分支 1.首先查看源码状态 git status 2.添加到暂存区 git add . git status //添加到暂存区后再次查看源码状态 3.提交代码到本 ...
- (代替人类)很多操作都在Settings里面。 5.安装第三方库
2020-02-01 pycharm 使用教程 LingSmart关注 0.0842020.02.07 15:08:50字数 1,394阅读 680 实在无聊,就来学习吧.学习pycharm的使用教程 ...
- Ubuntu 20.04 配置多网卡链路聚合
Ubuntu 20.04 配置多网卡链路聚合 多网卡IP配置 首先查看网卡信息 root@it:~# ip add 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65 ...