P8436 【模板】边双连通分量
【模板】边双连通分量
题目描述
对于一个 个节点 条无向边的图,请输出其边双连通分量的个数,并且输出每个边双连通分量。
输入格式
第一行,两个整数 和 。
接下来 行,每行两个整数 ,表示一条无向边。
输出格式
第一行一个整数 表示边双连通分量的个数。
接下来的 行,每行第一个数 表示该分量结点个数,然后 个数,描述一个边双连通分量。
你可以以任意顺序输出边双连通分量与边双连通分量内的结点。
样例 #1
样例输入 #1
5 8 1 3 2 4 4 3 1 2 4 5 5 1 2 4 1 1
样例输出 #1
1 5 1 5 4 2 3
样例 #2
样例输入 #2
5 3 1 2 2 3 1 3
样例输出 #2
3 3 1 3 2 1 4 1 5
样例 #3
样例输入 #3
6 5 1 3 2 4 1 2 4 6 2 3
样例输出 #3
4 3 1 2 3 1 4 1 5 1 6
样例 #4
样例输入 #4
7 8 1 3 2 4 3 5 2 5 6 4 2 5 6 3 2 7
样例输出 #4
3 1 1 5 2 5 3 6 4 1 7
提示
样例四解释:
相同颜色的点为同一个连通分量。
注:本题中边双连通分量指删除分量的任意一条边,依然连通的分量。
数据范围:
对于 的数据,,。
- 对于其中 的数据,,。
- 对于另外 的数据,,。
- 对于另外 的数据,,。
- 对于另外 的数据,,。
本题不卡常,时间限制与空间限制均已开大,正确的解法均可通过。
惊喜:AC 后记得把鼠标放到测试点上看反馈信息,有惊喜哦。
ps:刚才发了点双连通分量的模板题,顺便把边双连通分量的也发一下,求边双连通分量的代码解释可以看这一篇博客
// Problem: P8436 【模板】边双连通分量 // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P8436 // Memory Limit: 256 MB // Time Limit: 2000 ms // Created Time: 2022-07-22 15:03:11 // // Powered by CP Editor (https://cpeditor.org) //fw #include<iostream> #include<cstdio> #include<fstream> #include<algorithm> #include<cmath> #include<deque> #include<vector> #include<queue> #include<string> #include<cstring> #include<map> #include<stack> #include<set> #include<climits> #define zp ios::sync_with_stdio(false);cin.tie(0); cout.tie(0); #define pii pair <int, int> #define endl '\n' #define pb push_back #define lc u<<1 #define rc u<<1|1 using namespace std; typedef long long ll; const int INF=0x3f3f3f3f; const int N=5e5+10,M=4e6+10; int dfn[N],low[N],times,stk[N],top,dcc_cnt,n,m; bool is_bridge[M]; vector<int>dcc[N]; int h[N],e[M],ne[M],idx; void add(int a,int b) { e[idx]=b; ne[idx]=h[a]; h[a]=idx++; } void tarjan(int u,int from) { dfn[u]=low[u]=++times; stk[++top]=u; for(int i=h[u];~i;i=ne[i]) { int j=e[i]; if(!dfn[j]) { tarjan(j,i); low[u]=min(low[u],low[j]); if(dfn[u]<low[j]) is_bridge[i]=is_bridge[i^1]=1; } else if (i!=(from^1)) low[u]=min(low[u],dfn[j]); } if(low[u]==dfn[u]) { ++dcc_cnt; int y; do { y=stk[top--]; dcc[dcc_cnt].push_back(y); }while(y!=u); } } int main() { memset(h,-1,sizeof h); cin>>n>>m; while(m--) { int a,b; cin>>a>>b; add(a,b); add(b,a); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,-1); cout<<dcc_cnt<<endl; for(int i=1;i<=dcc_cnt;i++) { cout<<dcc[i].size(); for(auto l:dcc[i]) cout<<" "<<l; cout<<endl; } return 0; }
一个菜鸡
本文作者:Avarice_Zhao
本文链接:https://www.cnblogs.com/avarice/p/16505877.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步