tarjan 全WA求调

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

zhang_jinghan @ 2024-07-17 22:36:16

#include<iostream>
#include<cstring>
#include<cmath>
#include<stack>
#include<algorithm>
using namespace std;
struct Edge{
    int v,next;
}edge[100005];
int head[10005];
void add(int k,int u,int v){
    edge[k].v=v;
    edge[k].next=head[u];
    head[u]=k;
    return;
}
bool cmp(stack<int>a,stack<int>b){
    return a.top()<b.top();
}
int n,m;
bool flag[10005],instack[10005];
int dfn[10005],low[10005],tot;
stack<int>sta[10005];
int sta_tot=1;
void tarjan(int u){
    dfn[u]=++tot;
    low[u]=dfn[u];
    flag[u]=false;
    instack[u]=true;
    for(int i=head[u];i!=-1;i=edge[i].next){
        if(flag[edge[i].v]){
            tarjan(edge[i].v);
            low[u]=min(low[u],low[edge[i].v]);
        }else{
            if(instack[edge[i].v]){
                low[u]=min(low[u],dfn[edge[i].v]);
            }else{
                low[u]=min(low[u],low[edge[i].v]);
            }
        }
    }
    sta[sta_tot].push(u);
    if(low[u]==dfn[u]){
        sta_tot++;
    }
    instack[u]=false;
    return;
}
int main(){
    memset(head,-1,sizeof(head));
    memset(flag,true,sizeof(flag));
    cin>>n>>m;
    int u,v;
    for(int i=1;i<=m;i++){
        cin>>u>>v;
        if(u!=v){
            add(i,u,v);
        }
    }
    for(int i=1;i<=n;i++){
        if(flag[i]){
            tarjan(i);
        }
    }
    cout<<sta_tot-1<<endl;
    for(int i=1;i<sta_tot;i++){
        sort(sta+1,sta+sta_tot,cmp);
    }
    int ans[10005],ans_tot=0;
    for(int i=1;i<sta_tot;i++){
        ans_tot=0;
        while(! sta[i].empty()){
            ans[++ans_tot]=sta[i].top();
            sta[i].pop();
        }
        sort(ans+1,ans+1+ans_tot);
        for(int j=1;j<=ans_tot;j++){
            cout<<ans[j]<<' ';
        }
        cout<<endl;
    }
    return 0;
}

by I_will_AKIOI @ 2024-07-17 23:23:23

有没有可能你 tarjan 写错了,应该是长这样的:

void dfs(int k)
{
    dfn[k]=low[k]=++cnt;
    s[++len]=k;
    in[k]=1;
    for(int now:v[k])
    {
        if(!dfn[now]) dfs(now),low[k]=min(low[k],low[now]);
        else if(in[now]) low[k]=min(low[k],low[now]);
    }
    if(dfn[k]==low[k])
    {
        int now;
        SCC++;
        do
        {
            now=s[len--];
            in[now]=0;
            ans[SCC].push_back(now);
            f[now]=SCC;
        }
        while(now!=k);
    }
}

by I_will_AKIOI @ 2024-07-17 23:24:40

就是说在 if(low[u]==dfn[u]) 里面需要弹栈,加上记录一些其他东西。


|