用十字链表结构写的,根据数据结构书上的描述和自己的理解实现。但理解的不透彻,所以不知道有没有错误。但实验了几个都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. Mysql CPU占用90%

    今天网站打开卡,查了下发现Mysql CPU占用到90%! 1.通过putty工具连接mysql putty工具十分的强大,它可以让我们直接访问MySQL.当然,要实现这一步肯定要做点什么.MySQL ...

  2. 利用WCF技术降低系统之间的耦合度

    为了降低本系统各个组件之间的耦合度,本系统将BLL层采用WCF技术发布为Web Service,以供UI层调用. 前面我们已经介绍过,为什么UI层不直接调用BLL层,而是要经过UI->Servi ...

  3. 关于SVN代码提交粒度和频率的思考

    今天组内新来的一个同事问我代码提交频率的问题,他在上家公司是一个模块功能开发自测完成后再提交.而我这边采用的是最少一天提交一次,提倡粒度较小的提交, 而且是基于主干开发.采用这种方式是出于以下几点考虑 ...

  4. ECshop安装及报错解决方案总结

    一.安装ECshop ECShop是一款B2C独立网店系统 ,适合企业及个人快速构建个性化网上商店.系统是基于PHP语言及MYSQL数据库构架开发的跨平台开源程序.2006年3月推出以来1.0版以来, ...

  5. Hibernate框架之入门案例

    今天终于开始学习了三大框架的其中一个框架,Hibernate框架,在这里不去讲Hibernate框架的一些基础概念了,直接切入代码,带大家了解一下Hibernate能干什么, Hibernate的人们 ...

  6. PYTHONPATH 可以跨版本 方便使用 (本文为windows方法)转~

    PYTHONPATH是Python搜索路径,默认我们import的模块都会从PYTHONPATH里面寻找. 使用下面的代码可以打印PYTHONPATH: print(os.sys.path) 我的某个 ...

  7. 查看SQL Server日志 Part 1

    曾经有朋友问我数据被删除了,不借助第三方工具能不能查是什么时候发生的. SQL Server提供了一个undocumented的函数fn_dblog可以让我们查看活动的transaction log. ...

  8. ajax验证登录注册

    <form id="form1" onsubmit="return false;"> <table id="login-table& ...

  9. iOS开发——UI进阶篇(五)通知、代理、kvo的应用和对比,购物车

    一.通知 1.通知中心(NSNotificationCenter)每一个应用程序都有一个通知中心(NSNotificationCenter)实例,专门负责协助不同对象之间的消息通信任何一个对象都可以向 ...

  10. Python自动化之配置Python模块国内镜像

    Linux环境 在~/.pip/pip.conf文件中添加或修改 [global] index-url = http://mirrors.aliyun.com/pypi/simple/ [instal ...