tarjan
目的:求极大强联通分量
复杂度:O(n+m);
dfn[]表示这个点是第几次被dfs到的
low[]指极大强联通分量中最先被dfs到的,如果dfn[]==low[]那么它就是极大强联通分量中的祖先
用栈储存
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath> 6 #include<ctime> 7 #include<set> 8 #include<map> 9 #include<stack> 10 #include<cstring> 11 #define inf 2147483647 12 #define ls rt<<1 13 #define rs rt<<1|1 14 #define lson ls,nl,mid,l,r 15 #define rson rs,mid+1,nr,l,r 16 #define N 100010 17 #define For(i,a,b) for(int i=a;i<=b;i++) 18 #define p(a) putchar(a) 19 #define g() getchar() 20 21 using namespace std; 22 struct node{ 23 int n; 24 node *next; 25 }*e[1010]; 26 27 int dfn[1010],low[1010]; 28 stack<int>s; 29 bool vis[1010]; 30 int now,tot; 31 int x,y; 32 int n,m; 33 void in(int &x){ 34 int y=1; 35 char c=g();x=0; 36 while(c<'0'||c>'9'){ 37 if(c=='-')y=-1; 38 c=g(); 39 } 40 while(c<='9'&&c>='0'){ 41 x=(x<<1)+(x<<3)+c-'0';c=g(); 42 } 43 x*=y; 44 } 45 void o(int x){ 46 if(x<0){ 47 p('-'); 48 x=-x; 49 } 50 if(x>9)o(x/10); 51 p(x%10+'0'); 52 } 53 54 void push(int x,int y){ 55 node *p; 56 p=new node(); 57 p->n=y; 58 if(e[x]==0) 59 e[x]=p; 60 else{ 61 p->next=e[x]->next; 62 e[x]->next=p; 63 } 64 } 65 66 void tarjan(int x){ 67 dfn[x]=low[x]=++tot; 68 vis[x]=true; 69 s.push(x); 70 for(node *i=e[x];i;i=i->next){ 71 if(!dfn[i->n]){ 72 tarjan(i->n); 73 low[x]=min(low[x],low[i->n]); 74 } 75 else 76 if(vis[i->n]) 77 low[x]=min(low[x],dfn[i->n]); 78 } 79 if(low[x]==dfn[x]){ 80 do{ 81 now=s.top(); 82 o(now);p(' '); 83 s.pop(); 84 vis[now]=false; 85 }while(x!=now); 86 p(' '); 87 } 88 89 } 90 91 int main(){ 92 in(n);in(m); 93 For(i,1,m){ 94 in(x);in(y); 95 push(x,y); 96 } 97 For(i,1,n) 98 if(!dfn[i]) 99 tarjan(i); 100 return 0; 101 }