dongzimo @ 2024-10-25 16:56:08
#include<bits/stdc++.h>
using namespace std;
int n,m,u,v,cnt,sc;
vector<int> g[10005];
stack<int> s;
priority_queue<int,vector<int>,greater<int> >scc[10005];//记录强连通分量中包含的节点
int dfn[10005],low[10005],idx;
bool vis[10005];
int sccc[10005];//记录节点所在的强连通分量
void tarjan(int x){
dfn[x]=low[x]=++cnt;
vis[x]=1;
s.push(x);
for(int i=0;i<g[x].size();i++){
int idx=g[x][i];
if(!dfn[idx]){
tarjan(idx);
low[x]=min(low[x],low[idx]);
}
else if(vis[idx])
low[x]=min(low[x],dfn[idx]);
}
if(low[x]==dfn[x]){
sc++;
scc[sc].push(x);
sccc[x]=sc;
while(s.top()!=x){
scc[sc].push(s.top());
s.pop();
sccc[s.top()]=sc;
vis[s.top()]=0;
}
s.pop();
vis[x]=0;
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>u>>v;
g[u].push_back(v);
}
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
cout<<sc<<endl;
bool flag;
for(int i=1;i<=n;i++){
idx=sccc[i];
if(!scc[idx].empty()){
while(!scc[idx].empty()){
cout<<scc[idx].top()<<' ';
scc[idx].pop();
if(scc[idx].empty())
cout<<endl;
}
}
}
return 0;
}
by terryjiang @ 2024-10-26 10:33:28
两个问题,一个建议
要用map判重边,比较u和v判断自环,不然会炸
原因未知,不过改成vector存每个强连通分量里的点再sort输出就调好了
注意到你定义了多个长度相同的数组,对于这些数组你可以定义一个常数N
const int N=1e5+10;
然后定义数组时调用N就行了
int dfn[N]
需要AC代码吱一声,不过最好还是根据建议自己再敲一遍
by terryjiang @ 2024-10-26 10:37:35
@dongzimo