P8435 【模板】点双连通分量
【模板】点双连通分量
题目描述
对于一个 个节点 条无向边的图,请输出其点双连通分量的个数,并且输出每个点双连通分量。
输入格式
第一行,两个整数 和 。
接下来 行,每行两个整数 ,表示一条无向边。
输出格式
第一行一个整数 表示点双连通分量的个数。
接下来的 行,每行第一个数 表示该分量结点个数,然后 个数,描述一个点双连通分量。
你可以以任意顺序输出点双连通分量与点双连通分量内的结点。
样例 #1
样例输入 #1
5 8 1 3 2 4 4 3 1 2 4 5 5 1 2 4 1 1
样例输出 #1
1 5 1 2 3 4 5
样例 #2
样例输入 #2
5 3 1 2 2 3 1 3
样例输出 #2
3 1 4 1 5 3 1 2 3
样例 #3
样例输入 #3
6 5 1 3 2 4 1 2 4 6 2 3
样例输出 #3
4 2 6 4 2 4 2 3 3 2 1 1 5
样例 #4
样例输入 #4
7 8 1 3 2 4 3 5 2 5 6 4 2 5 6 3 2 7
样例输出 #4
3 2 7 2 5 5 2 4 6 3 2 3 1
提示
样例四解释:
相同颜色的点为同一个分量里的结点。
注意:点双连通分量的定义为无向图的极大点双连通子图,而不是去掉割点后分成的子图。
温馨提示:
-
如果您只得了 20 pts,可能是您没有特判孤立点,孤立点也算一个点双连通分量。
-
如果您 WA 了测试点 1 和 11,可能是没有判自环。
数据范围:
对于 的数据,,。
- 对于其中 的数据,,。
- 对于另外 的数据,,。
- 对于其中 的数据,,。
- 对于另外 的数据,,。
本题不卡常,时间限制与空间限制均已开大,正确的解法均可通过。
惊喜:AC 后记得把鼠标放到测试点上看反馈信息,有惊喜哦。
ps:求点双连通分量的具体解释可以看这一篇tarjan vDCC缩点 模板,发这篇博客是因为求vDCC的时候被自环搞了
代码
// Problem: P8435 【模板】点双连通分量 // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P8435 // Memory Limit: 256 MB // Time Limit: 2000 ms // Created Time: 2022-07-22 14:00:43 // // 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 h[N],e[M],ne[M],idx,n,m; int dfn[N],low[N],times,stk[N],top,dcc_cnt,root; vector<int>dcc[N]; bool cut[N]; void add(int a,int b) { e[idx]=b; ne[idx]=h[a]; h[a]=idx++; } void tarjan(int u) { dfn[u]=low[u]=++times; stk[++top]=u; if(u==root&&h[u]==-1) { dcc_cnt++; dcc[dcc_cnt].push_back(u); return; } int cnt=0; for(int i=h[u];~i;i=ne[i]) { int j=e[i]; if(!dfn[j]) { tarjan(j); low[u]=min(low[u],low[j]); if(dfn[u]<=low[j]) { cnt++; if(u!=root||cnt>1)cut[u]=true; ++dcc_cnt; int y; do { y=stk[top--]; dcc[dcc_cnt].push_back(y); }while(y!=j); dcc[dcc_cnt].push_back(u); } } else low[u]=min(low[u],dfn[j]); } } int main() { memset(h,-1,sizeof h); cin>>n>>m; while(m--) { int a,b; cin>>a>>b; if(a!=b)//自环会出问题!!! { add(a,b); add(b,a); } } for(root=1;root<=n;root++) { if(!dfn[root]) tarjan(root); } 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/16505783.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步