tarjan求强连通分量模板

本文介绍了一种用于寻找图中的强连通分量的算法,并提供了完整的C++实现代码。通过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)

转载于:https://www.cnblogs.com/yz12138/p/5931774.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值