仅AC on #6求调

B3609 [图论与代数结构 701] 强连通分量

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

两个问题,一个建议

  1. 注意,本题可能存在重边和自环。

要用map判重边,比较u和v判断自环,不然会炸

  1. 优先队列的锅

原因未知,不过改成vector存每个强连通分量里的点再sort输出就调好了

以下是个人建议

注意到你定义了多个长度相同的数组,对于这些数组你可以定义一个常数N

const int N=1e5+10;

然后定义数组时调用N就行了

int dfn[N]

需要AC代码吱一声,不过最好还是根据建议自己再敲一遍


by terryjiang @ 2024-10-26 10:37:35

@dongzimo


|