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

求强连通分量

要用到时间戳的概念

算了 直接给模板

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 }

 

你可能感兴趣的:(模板)