Tarjan
2021/12/4 23:20:22
本文主要是介绍Tarjan,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1 #include <iostream> 2 3 using namespace std; 4 5 const int MAXN=100010; 6 const int MAXM=100010; 7 8 struct Edge 9 { 10 int to,next,w; 11 }e[MAXM*2]; 12 int head[MAXN]; 13 14 int cnt=0; 15 void addEdge(int x,int y,int z=1) 16 { 17 cnt++; 18 e[cnt].next=head[x]; 19 e[cnt].to=y; 20 e[cnt].w=z; 21 head[x]=cnt; 22 return; 23 } 24 25 int tot=0; //时间 26 int dfn[MAXN],low[MAXN]; //dfn-记录时间戳,low-根 27 int s[MAXN],idx=0; //栈数组,下标 28 bool instack[MAXN]; //是否在栈中 29 void tarjan(int x) //tarjan算法,实际上是一个dfs递归的过程 30 { 31 dfn[x]=low[x]=++tot; //更新时间戳和连通子图的根 32 s[++idx]=x; //进栈 33 instack[x]=true; //标记为在栈中 34 for (int i=head[x];i!=0;i=e[i].next) //遍历每条边的另一端(终点) 35 { 36 int j=e[i].to; //终点 37 if (!dfn[j]) //没访问过 38 { 39 tarjan(j); //继续dfs 40 low[x]=min(low[x],low[j]); //更新根 41 } 42 else if (instack[j]) low[x]=min(low[x],low[j]); //访问过且在栈中,更新根 43 //如果访问过且不在栈中,则说明已经形成一个连通子图 44 } 45 if (dfn[x]==low[x]) //时间戳和根相等,说明是根 46 { 47 do 48 { 49 cout<<s[idx]<<" "; 50 instack[s[idx]]=false; 51 idx--; 52 }while (x!=s[idx+1]); //出栈并输出 53 cout<<endl; 54 } 55 return; 56 } 57 58 int main() 59 { 60 int n,m; 61 cin>>n>>m; 62 int u,v; 63 for (int i=1;i<=m;i++) 64 { 65 cin>>u>>v; 66 addEdge(u,v); 67 } 68 for (int i=1;i<=n;i++) 69 { 70 if (!dfn[i]) tarjan(i); //没有时间戳,说明未访问过,则遍历,防止图没走完 71 } 72 73 return 0; 74 }
这篇关于Tarjan的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南