首页 > 代码库 > 【模板】有向图强连同分量

【模板】有向图强连同分量

求强连通分量

要用到时间戳的概念

算了 直接给模板

ps:借鉴大白皮的写法

 1 # include<cstdio> 2 # include<cstring> 3 # include<stack> 4 # include<algorithm> 5 using namespace std; 6 const int N=100000; 7 const int M=500000; 8 int n,m,dfs_clock,ecnt,scc_cnt; 9 int fist[N],next[M],v[M],pre[N],low[N],scc_no[N];10 stack<int>S;11 void built(int a,int b){12     v[++ecnt]=b;13     next[ecnt]=fist[a];14     fist[a]=ecnt;15 }16 void init(){17     int a,b;18     memset(fist,-1,sizeof(fist));19     scanf("%d%d",&n,&m);20     for(int i=1;i<=m;i++){21         scanf("%d%d",&a,&b);22         built(a,b);23     }24 }25 int dfs(int u){26     int lowu=pre[u]=++dfs_clock;27     int lowv;28     S.push(u);29     for(int e=fist[u];e!=-1;e=next[e])30     if(!pre[v[e]])31     lowu=min(lowu,lowv=dfs(v[e]));32     else if(!scc_no[v[e]])33     lowu=min(lowu,pre[v[e]]);34     low[u]=lowu;35     if(pre[u]==low[u]){36         scc_cnt++;37         for(;;){38             int x=S.top();S.pop();39             scc_no[x]=scc_cnt;40             if(x==u)break;41         }42     }43     return low[u];44 }45 void find_scc(){46     memset(pre,0,sizeof(pre));47     memset(scc_no,0,sizeof(scc_no));48     for(int i=1;i<=n;i++)49     if(!pre[i])dfs(i);50 }51 void print(){52     printf("%d",scc_cnt);53 }54 int main(){55     init();56     find_scc();57     print();58     return 0;59 }

 

【模板】有向图强连同分量