tarjan算法

(补充个题    牛客小白月赛12 I 题

大佬博客

https://www.sohu.com/a/245954819_100201031

https://www.cnblogs.com/shadowland/p/5872257.html

https://blog.csdn.net/acmmmm/article/details/16361033

ac代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
vector<int>a[maxn];
int dfn[maxn],low[maxn],vis[maxn],sk[maxn],color[maxn],cnt[maxn];;
int top,deep,red;
void tarjan(int u){
    dfn[u]=++deep;
    low[u]=deep;
    vis[u]=1;
    sk[++top]=u;
    int mx=a[u].size();
    for(int i=0;i<mx;i++){
        int v=a[u][i];
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else{
            if(vis[v])low[u]=min(low[u],low[v]);
        }
    }
    if(dfn[u]==low[u]){
        color[u]=++red;
        vis[u]=0;
        while(sk[top]!=u){
            color[sk[top]]=red;
            vis[sk[top]]=0;
            top--;
        }
        top--;
    }
}
int n,m,u,v;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        scanf("%d%d",&u,&v);
        a[u].push_back(v);
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i]){
            tarjan(i);
        }
    }
    //统计颜色
    for(int i=1;i<=n;i++){
        cnt[color[i]]++;
    }
    //统计组合
    int ans=0;
    for(int i=1;i<=m;i++){
        if(cnt[i]>1)ans++;

    }
    printf("%d\n",ans);
    return 0;
}