强连通图tarjan算法C语言实现
2013-09-02 00:38
281 查看
/******************************************
图的定义:
1->2->4->6->8->7->6
2->3->1
4->5->2
运行结果:
连通分量1: 7 8 6
连通分量2: 5 4 3 2 1
2 2 2 2 2 1 1 1
Press any key to continue
******************************************/
图的定义:
1->2->4->6->8->7->6
2->3->1
4->5->2
运行结果:
连通分量1: 7 8 6
连通分量2: 5 4 3 2 1
2 2 2 2 2 1 1 1
Press any key to continue
******************************************/
#include<iostream> #include<vector> using namespace std; const int MAX=10001; int Stop;//栈中的元素个数 int cnt;//记录连通分量的个数 int visitNum;//记录遍历的步数 int DFN[MAX]; //记录节点u第一次被访问时的步数 int LOW[MAX]; //记录与节点u和u的子树节点中最早的步数 bool instack[MAX];//记录节点u是否在栈中 int Stap[MAX];//栈 int Belong[MAX];//记录每个节点属于的强连通分量编号 int N;//节点个数 vector<int> tree[MAX]; void tarjan(int i) { int j; DFN[i]=LOW[i]=++visitNum; instack[i]=true; Stap[++Stop]=i;//将当前节点压入栈中 for (unsigned k=0;k<tree[i].size();k++) { j=tree[i][k]; if (!DFN[j]) //j还没有被访问过 { tarjan(j); //父节点是子节点的子节点 if (LOW[j]<LOW[i]) LOW[i]=LOW[j]; } //与j相连,但是j已经被访问过,且还在栈中 //用子树节点更新节点第一次出现的时间 else if (instack[j] && DFN[j]<LOW[i]) LOW[i]=DFN[j]; } //节点i是强连通分量的根 if (DFN[i]==LOW[i]) { cnt++; //输出找到的强连通分量 cout<<"连通分量"<<cnt<<": "; //退栈,直至找到根为止 do { j=Stap[Stop--]; instack[j]=false; cout<<j<<" "; Belong[j]=cnt; } while (j!=i); cout<<endl; } } void solve() { Stop=cnt=visitNum=0; memset(DFN,0,sizeof(DFN)); for (int i=1;i<=N;i++) if (!DFN[i])//有可能图不是连通图 tarjan(i); } int main() { #if 0 N=6; tree[1].push_back(3); tree[1].push_back(2); tree[2].push_back(4); tree[3].push_back(5); tree[3].push_back(4); tree[4].push_back(1); tree[4].push_back(6); tree[5].push_back(6); #else N=8; tree[3].push_back(1); tree[1].push_back(2); tree[2].push_back(3); tree[2].push_back(4); tree[5].push_back(2); tree[4].push_back(5); tree[4].push_back(6); tree[5].push_back(6); tree[6].push_back(8); tree[8].push_back(7); tree[7].push_back(6); #endif solve(); for(int i=1;i<=N;i++) cout<<Belong[i]<<" "; cout<<endl; return 0; }
相关文章推荐
- 利用栈实现简单计算器的例子(Calculator)
- VB.NET实现DirectSound9 (8) 音效控制器
- jsp实现文件上传
- .net之旅-树型结构及相关功能的实现(41)
- datable添加列实现了.但是怎么把数据绑定到这个列中?????
- gridview 实现全选和反选--补充
- Java Web中的入侵检测及简单实现
- 动态会签中动态实现任务可见性
- 实现动态链接库
- C#实现屏幕键盘(软键盘 ScreenKeyboard)
- struts实现文件上传程序
- 一步步教你实现富文本编辑器(第四部分)
- 三种模拟自动登录和提交POST信息的实现方法
- 数据结构实现(插入排序、快速排序、统计排序类模板)
- 实现 SPY++ 的 FindWindow Tool 的高亮
- 中断实现LOOP功能
- Android项目之---ListView实现论坛管理效果
- 利用多线程实现对网站状态的监控
- 不一样的课程表,不一样的Excle--用Excle进行设计(20):顺序结构的实现