tarjan求强连通分量模板

 

 

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <string>
 7 #include <string.h>
 8 #define gc getchar()
 9 using namespace std;
10 int n,m;
11 int g[233333]={};
12 int DFN[233333];
13 int Low[233333];
14 int cnt=0;
15 int stack[233333];
16 bool v[233333]={};
17 bool instack[233333]={};
18 int top=0;
19 int Index=0;
20 struct node
21 {
22     int to,next;
23 }e[466666];
24 int t[233333];
25 int ax=0;
26 void addedge(int x,int y)
27 {
28     e[++cnt].next=g[x];
29     g[x]=cnt;
30     e[cnt].to=y;
31 }
32 int read()
33 {
34     int xxxx=0,fuh=1;char ch=gc;
35     while(!isdigit(ch)){
36         if(ch=='-')fuh=-1;
37         ch=gc;
38     }
39     while(isdigit(ch)){
40         xxxx=(xxxx<<3)+(xxxx<<1)+ch-'0';ch=gc;
41     }
42     return xxxx*fuh;
43 }
44 void tarjan(int u) 
45 {
46     int i;
47     DFN[u]=Low[u]=++Index;     // 为节点u设定次序编号和Low初值
48     stack[++top]=u;    
49     instack[u]=1;               // 将节点u压入栈中
50     for (i=g[u];i;i=e[i].next)   // 枚举每一条边
51       {            
52         if (!DFN[e[i].to])      // 如果节点v未被访问过
53           {    
54              tarjan(e[i].to);            // 继续向下找
55              Low[u]=min(Low[u],Low[e[i].to]);
56           }
57         else 
58           if (instack[e[i].to])            // 如果节点v还在栈内
59             Low[u]=min(Low[u],DFN[e[i].to]);
60     }
61     if(DFN[u]==Low[u])
62         while(stack[top+1]!=u)
63           {
64             ++t[u];
65             instack[stack[top--]]=false;
66         }
67 }
68 int main()
69 {
70     n=read();m=read();int t1,t2;
71     for (int i=1;i<=m;i++)
72       {
73           t1=read();
74         t2=read();
75         addedge(t1,t2);
76       }
77   
78     for(int i=1;i<=n;i++) 
79       if(!DFN[i])  tarjan(i);
80     cout<<*max_element(t+1,t+n+1);
81     return 0;
82 }
View Code

 

  1. if (DFN[u] == Low[u])                      // 如果节点u是强连通分量的根  
  2.         repeat  
  3.             v = S.pop                  // 将v退栈,为该强连通分量中一个顶点  
  4.             print v  
  5.         until (u== v)
posted @ 2016-10-05 09:52  yz12138  阅读(208)  评论(0)    收藏  举报