图论(五)--强连通分量
来源:互联网 发布:手机数据魔方 编辑:程序博客网 时间:2024/06/05 07:26
基于算法导论图算法-强连通分量
- 题目描述
- 问题分析
- 源代码
- 结果截图
题目描述
求图的连通分量
问题分析
先对原图进行DFS,在根据结束时间的倒序对原图的转置进行DFS即可,具体证明可以参考算法导论第22章22.5节-强连通分量。
伪代码及算法复杂度:
源代码
Graph G_Transpose(Graph G);//求图的转置void strongly_connected_components(Graph G);//求强连通分量void DFS_G_T(Graph G);//对图的转置按照结束时间递减顺序DFS
int Time;int finishTime_descreasing[VertexNum + 1];//在深搜时按结束时间存int count_finishTime_descreasing = VertexNum;//数组下标,从后往前存void DFS_visit_stack(Graph G, Vertex v) {//深搜用栈实现 PtrToNode ptr; stack<int> S; S.push(v); G->vertices[v].dist = 0; G->vertices[v].color = 1;//灰色 G->vertices[v].discover_time = ++Time; printf("%d", v); while (!S.empty()) { Vertex u = S.top(); ptr = G->vertices[u].adjto; while (ptr != NULL) { if (G->vertices[ptr->adjvex].color == 0) { S.push(ptr->adjvex); G->vertices[ptr->adjvex].dist = G->vertices[u].dist + 1;//权为1计算 G->vertices[ptr->adjvex].color = 1;//灰色 Time++; G->vertices[ptr->adjvex].discover_time = Time; G->vertices[ptr->adjvex].pred = u; printf(" %d", ptr->adjvex); break; } ptr = ptr->next; } if (S.top() == u) { G->vertices[u].color = 2;//黑色 Time++; G->vertices[u].finish_time = Time; finishTime_descreasing[--count_finishTime_descreasing] = u; S.pop(); } } printf("\n");}void DFS(Graph G) { for (int i = 0; i < G->vexnum; i++) { G->vertices[i].color = 0;//白色 G->vertices[i].pred = -1; } Time = 0; for (int i = 0; i < G->vexnum; i++) { if (G->vertices[i].color == 0) { DFS_visit_stack(G, i); } }}Graph G_Transpose(Graph G) {//求图的转置 Graph G_T; PtrToNode ptr, node; //创建图的初始化 G_T = (struct GraphRecord*)malloc(sizeof(struct GraphRecord)); G_T->vexnum = G->vexnum; G_T->vertices = (struct VertexRecord*)malloc(sizeof(struct VertexRecord)*G_T->vexnum); for (int i = 0; i < G_T->vexnum; i++) { G_T->vertices[i].adjto = NULL; G_T->vertices[i].in_degree = 0; G_T->vertices[i].out_degree = 0; } //创建图 for (int i = 0; i < G->vexnum; i++) { ptr = G->vertices[i].adjto; while (ptr != NULL) { node = (struct Node*)malloc(sizeof(struct Node)); node->adjvex = i; node->next = G_T->vertices[ptr->adjvex].adjto; G_T->vertices[ptr->adjvex].adjto = node; ptr = ptr->next; } } //print_graph(G_T);打印转置图 return G_T;}void DFS_G_T(Graph G) { int count = 0; for (int i = 0; i < G->vexnum; i++) { G->vertices[i].color = 0;//白色 G->vertices[i].pred = -1; } Time = 0; for (int i = 0; i < G->vexnum; i++) { if (G->vertices[finishTime_descreasing[i]].color == 0) { printf("第%d个强连通分量:", ++count); //DFS_VISIT(G, i); DFS_visit_stack(G, finishTime_descreasing[i]); //print_dist_dfs(G, finishTime_descreasing[i]); } } printf("共有%d个强连通分量\n", count); //print_path_everyPoint(G); //print_dist_dfs(G, 0);}void strongly_connected_components(Graph G) { printf("深搜G:"); DFS(G); Graph G_T = G_Transpose(G); /*for (int i = 0; i < VertexNum; i++) {//按递减顺序打印结束时间 printf("顶点%d的结束时间为:%d\n", finishTime_descreasing[i], G->vertices[finishTime_descreasing[i]].finish_time); }*/ printf("按照递减顺序dfs原图的转置得到强连通分量:\n"); DFS_G_T(G_T);}int main() { CreateRandomDirectGraph(); Graph G = CreateDirectGraph();//参考[图论(一)-图的建立](http://blog.csdn.net/deep_kang/article/details/70877468),这里以十个顶点做测试 printf("打印图结构:\n"); print_graph(G);//打印图 printf("\n求强连通分量:\n"); strongly_connected_components(G); return 0;}
结果截图
0 0
- 图论(五)--强连通分量
- 强连通分量 (转)
- 强连通分量(桥)
- 强连通分量(kosaraju)
- 强连通分量(Tarjan)
- 强连通分量(模板)
- 强连通分量(方法)
- 图论:POJ2186-Popular Cows (求强连通分量)
- 【图论】强连通分量和拓扑排序
- POJ2186 Popular Cows 【图论】【强连通分量】
- 图论-强连通分量 poj-2186
- poj 1236(tarjam)强连通分量
- poj-2553(强连通分量)
- 强连通分量SCC模版(LRJ)
- Strongly connected(hdu4635(强连通分量))
- 迷宫城堡(hdu1269,强连通分量)
- hdu 4635(强连通分量)
- 强连通分量(LRJ训练指南)
- Codeforces gym 101102 D 单调栈
- POJ2080简单模拟
- Linux基础学习笔记之文件类型
- 网络编程基础
- Javascript基础学习(二)
- 图论(五)--强连通分量
- 常见错误
- java.langNoClassdefFoundError & java.lang.ClassNotFoundException
- ubuntu锁屏后,字符密码无法输入
- Swift3字符串转换为其他数据类型
- 重构:改善既有代码的设计
- Vue-router总结
- 选择排序(Selection Sort)
- 2132: 中南大学2017年ACM暑期集训前期训练题集(入门题)