【板子】强连通分量(SCC)

//强连通分量
//lg 2863 求强连通分量的数量
#include<bits/stdc++.h>
using namespace std;

const int N = (int)2e4+4;

int where[N];//这个点在哪个scc里
int scccnt;
int sccsize[N];
int low[N],dfn[N],idx;
bool instk[N];
stack<int> stk;

vector<int> e[N];
int n,m;

void Tarjan(int u)
{
    dfn[u]=low[u]=++idx;
    instk[u]=true;
    stk.push(u);
    for(int v : e[u])
    {
        if(!dfn[v])
        {
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instk[v])
        {
            low[u]=min(low[u],dfn[v]);
            //low[u]=min(low[u],low[v]);
        }
    }
    if(dfn[u]==low[u])
    {
        scccnt++;
        while(stk.top()!=u)
        {
            instk[stk.top()]=false;
            where[stk.top()]=scccnt;
            sccsize[scccnt]++;
            stk.pop();
        }
        sccsize[scccnt]++;
        where[u]=scccnt;
        instk[u]=false;
        stk.pop();
    }
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        e[u].push_back(v);
    }
    for(int i=1;i<=n;i++)
    {
        Tarjan(i);
    }
    int cnt=0;
    for(int i=1;i<=scccnt;i++)
    {
        if(sccsize[i]>1) cnt++;
    }
    cout<<cnt;
    return 0;
}
posted @ 2024-01-26 20:51  yeyou26  阅读(11)  评论(0编辑  收藏  举报