B3609 [图论与代数结构 701] 强连通分量(强连通分量)
B3609 [图论与代数结构 701] 强连通分量
题目描述
给定一张
注意,本题可能存在重边和自环。
输入格式
第一行两个正整数
接下来
输出格式
第一行一个整数表示这张图的强连通分量数目。
接下来每行输出一个强连通分量。第一行输出 1 号点所在强连通分量,第二行输出 2 号点所在强连通分量,若已被输出,则改为输出 3 号点所在强连通分量,以此类推。每个强连通分量按节点编号大小输出。
输入输出样例 #1
输入 #1
6 8
1 2
1 5
2 6
5 6
6 1
5 3
6 4
3 4
输出 #1
3
1 2 5 6
3
4
说明/提示
对于所有数据,
这道题是一道标准的强连通分量的题,但我还是卡了好久,首先对于自环我们只需要判断a1=b就行了,对于重边,我用的是set容器,然后在出栈的时候我们需要存储每个点在第几个强连通分量当中,然后在遍历的过程中,如果改点所对应的强连通分量已经输出了,说明该点就已经输出了,此时我们直接跳过就行
#include<iostream>
#include<vector>
#include<stack>
#include<set>
#include<algorithm>
using namespace std;
const int N=1e5+5;
int n,m,a,b;
int low[N],dfsn[N],vis[N];
set<int>v[N];
vector<int>ans[N];
int vis1[N];
int vis2[N];
stack<int>s;
int t=0,cnt=0;
void dfs(int x){
low[x]=dfsn[x]=++t;
vis[x]=1;
s.push(x);
for(auto i=v[x].begin();i!=v[x].end();i++){
int y=*i;
if(!dfsn[y]){
dfs(y);
low[x]=min(low[x],low[y]);
}
else if(vis[y])low[x]=min(low[x],dfsn[y]);
}
if(low[x]==dfsn[x]){
++cnt;
while(s.top()!=x){
ans[cnt].push_back(s.top());
vis1[s.top()]=cnt;
vis[s.top()]=0;
s.pop();
}
ans[cnt].push_back(s.top());
vis1[s.top()]=cnt;
vis[s.top()]=0;
s.pop();
}
}
int main(){
cin>>n>>m;
while(m--){
cin>>a>>b;
if(a!=b)v[a].insert(b);
}
for(int i=1;i<=n;i++)if(!dfsn[i])dfs(i);
cout<<cnt;
cout<<endl;
for(int i=1;i<=n;i++){
int w=vis1[i];
if(vis2[w])continue;
vis2[w]=1;
sort(ans[w].begin(),ans[w].end());
for(int j=0;j<ans[w].size();j++)cout<<ans[w][j]<<" ";
cout<<endl;
}
return 0;
}
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合终身会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 突发,CSDN 崩了!程序员们开始慌了?
· 完成微博外链备案,微博中直接可以打开园子的链接
· C# WinForms 实现打印监听组件
· C#实现欧姆龙 HostLink 通讯协议库
· 一个基于 .NET 开源、模块化 AI 图像生成 Web 用户界面