用十字链表结构写的,根据数据结构书上的描述和自己的理解实现。但理解的不透彻,所以不知道有没有错误。但实验了几个都ok.

#include <iostream>
#include <vector>
using namespace std; //有向图十字链表表示
#define MAX_VERTEX_NUM 20 typedef struct ArcBox{
int tailvex, headvex; //该弧尾和头顶点的位置
struct ArcBox *hlink, *tlink; //分别指向弧头相同和弧尾相同的弧的链域
}ArcBox; typedef struct VexNode{
int data;
ArcBox *firstin, *firstout;//分别指向该顶点的第一条入弧和出弧
}VexNode; typedef struct{
VexNode xlist[MAX_VERTEX_NUM]; //表头向量
int vexnum, arcnum; //有向图的顶点数和弧数
}OLGraph; //定位顶点在xlist中的位置
int LocateVex(OLGraph G, int data)
{
for(int i = ; i < G.vexnum; i++)
{
if(G.xlist[i].data == data)
{
return i;
}
}
cout << "error the vertex "<< data << " is not in the list"<<endl;
return -;
} //有向图十字链表创建
void CreateDG(OLGraph &G)
{
cout << "please input the number of vertex, the number of arc:";
cin >> G.vexnum >> G.arcnum; for(int i = ; i < G.vexnum; i++)
{
cout << "please input vertex data:";
cin >> G.xlist[i].data; G.xlist[i].firstin = NULL; //初始化指针
G.xlist[i].firstout = NULL;
} for(int k = ; k < G.arcnum; k++)
{
int v1, v2; //弧的尾和头
cout << "please input the tail and head vertex of each tail:";
cin >> v1 >> v2; int i = LocateVex(G, v1);
int j = LocateVex(G, v2);
ArcBox * p = new ArcBox;
p->headvex = j;
p->tailvex = i;
p->hlink = G.xlist[j].firstin;
p->tlink = G.xlist[i].firstout; G.xlist[j].firstin = p;
G.xlist[i].firstout = p;
}
} //单向深度优先搜索
//输入: 图G, 开始遍历点v, 遍历标志visited, 遍历方向dir 0 表示从尾向头遍历 1表示从头到尾遍历, vecor存放跳出遍历的顺序
void DFS(OLGraph G, int v, int * visited, int dir, vector<int> * vec)
{
visited[v] = ;
(*vec).push_back(v);
if(dir == ) //从尾向头遍历
{
ArcBox * w = G.xlist[v].firstout;
while(w != NULL ) //注意 这里的while
{
if(visited[w->headvex] == )
{
w = w->tlink;
}
else//未访问过该点 递归遍历该点
{
DFS(G, w->headvex, visited, dir, vec);
w = w->tlink;
}
}
}
else //从头向尾遍历
{
ArcBox * w = G.xlist[v].firstin;
while(w != NULL)//查找下一个遍历点
{
if((visited[w->tailvex]) == )
{
w = w->hlink;
}
else//未访问过该点 递归遍历该点
{
DFS(G, w->tailvex, visited, dir, vec);
w = w->hlink;
}
}
}
} //查找有向图强连通分量
vector<vector<int>> FindConnectedPart(OLGraph G)
{
vector<vector<int>> ConnectedPart;
vector<vector<int>> finished;
int* visited = new int[G.vexnum];
memset(visited, , G.vexnum * sizeof(int)); //初始化为全部没有访问过 //从尾向头遍历
for(int v = ; v < G.vexnum; v++)
{
if(visited[v] == ) //没有被访问过
{
vector<int> vec;
DFS(G, v, visited, , &vec);
finished.push_back(vec);
}
} //从头向尾遍历
memset(visited, , G.vexnum * sizeof(int));
vector<int>::iterator it;
vector<vector<int>>::iterator it2;
int* find = new int[G.vexnum]; //find标识顶点实际上是否被查找过
for(int i = ; i < G.vexnum; i++)
{
find[i] = ;
visited[i] = ;
}
for(it2 = finished.begin(); it2 < finished.end(); it2++)
{
//已经遍历过的部分visited不变,即都是1; find[i]= 0的表示本次遍历时不遍历结点i,为了跳过i,设它们的visited[i]=1; 但实际上,它们还没有被访问到
//比如从尾到头遍历时得到两个分量 (1,2,3,4)(5)
//那么为了找到重连通分量,从头到尾遍历4,3,2,1时不应该经过5 即可能从头到尾遍历时的分量是(1 2 3 5)(4)
// 但实际上重连通分量为(1,2,3)(4)(5)三个
for(it = it2->begin(); it < it2->end(); it++)
{
visited[*it] = ; //只把本次遍历考虑到的顶点的visited设为0,其他为1,就不会加人遍历了
find[*it] = ;
} for(it = it2->begin(); it < it2->end(); it++)
{
if(visited[*it] == ) //没有被访问过
{
vector<int> vec;
DFS(G, *it, visited, , &vec);
ConnectedPart.push_back(vec);
}
}
} //输出重连通分量
int n = ;
cout << "重连通分量有:" << endl;
for(it2 = ConnectedPart.begin(); it2 < ConnectedPart.end(); it2++)
{
cout << ++n << ":";
for(it = it2->begin(); it < it2->end(); it++)
{
cout << G.xlist[*it].data << " ";
}
cout<< endl;
} delete [] visited;
delete [] find;
return ConnectedPart;
} int main()
{
OLGraph G;
CreateDG(G);
FindConnectedPart(G); return ;
}

http://blog.csdn.net/wsniyufang/article/details/6604458里面有将更好的算法。我还没看。

【数据结构】DFS求有向图的强连通分量的更多相关文章

  1. 图论-求有向图的强连通分量(Kosaraju算法)

    求有向图的强连通分量     Kosaraju算法可以求出有向图中的强连通分量个数,并且对分属于不同强连通分量的点进行标记. (1) 第一次对图G进行DFS遍历,并在遍历过程中,记录每一个点的退出顺序 ...

  2. Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量

    在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...

  3. Tarjan算法 求 有向图的强连通分量

    百度百科 https://baike.baidu.com/item/tarjan%E7%AE%97%E6%B3%95/10687825?fr=aladdin 参考博文 http://blog.csdn ...

  4. Tarjan算法求有向图的强连通分量

    算法描述 tarjan算法思想:从一个点开始,进行深度优先遍历,同时记录到达该点的时间(dfn记录到达i点的时间),和该点能直接或间接到达的点中的最早的时间(low[i]记录这个值,其中low的初始值 ...

  5. (转)求有向图的强连通分量个数(kosaraju算法)

    有向图的连通分量的求解思路 kosaraju算法 逛了很多博客,感觉都很难懂,终于找到一篇能看懂的,摘要记录一下 原博客https://www.cnblogs.com/nullzx/p/6437926 ...

  6. 求有向图的强连通分量个数 之 Kosaraju算法

    代码: #include<cstdio> #include<cstring> #include<iostream> using namespace std; ][] ...

  7. 图->连通性->有向图的强连通分量

    文字描述 有向图强连通分量的定义:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly co ...

  8. DFS的运用(二分图判定、无向图的割顶和桥,双连通分量,有向图的强连通分量)

    一.dfs框架: vector<int>G[maxn]; //存图 int vis[maxn]; //节点访问标记 void dfs(int u) { vis[u] = ; PREVISI ...

  9. uva11324 有向图的强连通分量+记忆化dp

    给一张有向图G, 求一个结点数最大的结点集,使得该结点集中任意两个结点u和v满足,要么u可以到达v, 要么v可以到达u(u和v相互可达也可以). 因为整张图可能存在环路,所以不好使用dp直接做,先采用 ...

随机推荐

  1. 【CISP笔记】安全漏洞与恶意代码(2)

    恶意代码自我保护 进程保护 进程守护 超级权限 检测对抗 反动态调试 反静态调试 恶意代码检测技术 特征码扫描 沙箱技术 行为检测 恶意代码分析技术 静态分析 需要实际执行恶意代码,它通过对其二进制文 ...

  2. go学习与记录

    搭建go开发环境:http://studygolang.com/articles/5406 日志相关:https://github.com/hpcloud/tail go定时器:http://stud ...

  3. C#之类与对象

    这段代码告诉我们要把#define DEBUG放在文件的开头位置,不然会导致编译错误,最后还要#endif 以上代码告诉我们可以对自己创建的类设计自己的构造方法,然后可以通过具体的Main()函数来通 ...

  4. C语言各种标准的

    [K&R C] 1978 年,Dennis Ritchie 和 Brian Kernighan 合作推出了<The C Programming Language>的第一版(按照惯例 ...

  5. vim 编辑器的设置

    vi编辑器的配置:http://blog.mcuol.com/User/fenghua/Article/17411_1.htm ******************************vim ~/ ...

  6. Android 带清除功能的输入框控件ClearEditText,仿IOS的输入框

    转载请注明出处http://blog.csdn.net/xiaanming/article/details/11066685 今天给大家带来一个很实用的小控件ClearEditText,就是在Andr ...

  7. Unity手游之路<十一>资源打包Assetbundle

    http://blog.csdn.net/janeky/article/details/17652021 在手游的运营过程中,更新资源是比不可少的.资源管理第一步是资源打包.传统的打包可以将所有物件制 ...

  8. autolayout的各种坑

    xocde7的autolayout 在viewDidLoad之前, 使用frame改变布局是没有用的, 简单的视图才可以使用autolayout, 稍微复杂写的都要使用代码来编写 获取当前view的宽 ...

  9. 贴一下WC总结里提到的那道裸题吧。。。

    [bzoj4034][HAOI2015]T2 试题描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 ...

  10. SSH-Struts第一弹:ActionSupport类

    Action继承了com.opensymphony.xwork2.ActionSupport. package com.candy.login; import com.opensymphony.xwo ...